Gatsby React Router Scroll Management
gatsby-react-router-scroll is a Gatsby plugin designed to manage scroll behavior across page transitions, specifically within Gatsby applications that leverage `@reach/router`. It is a direct fork of `react-router-scroll`, which itself was an adaptation for React Router v4 from an earlier version, and has been further modified to be compatible with Gatsby's internal `@reach/router` usage. The current stable version is 6.16.0. As a utility tightly integrated with Gatsby, its release cadence generally aligns with Gatsby's main releases, typically seeing monthly minor updates and frequent patch releases. Its primary differentiation is its tight integration and optimization for the Gatsby ecosystem and its `@reach/router` dependency, providing a seamless scroll restoration experience without requiring extensive manual intervention, which is crucial for modern single-page application (SPA) navigation patterns.
Common errors
-
TypeError: Cannot read properties of undefined (reading 'location') or (reading 'action')
cause The `ScrollManager` component is not receiving the required `location` or `action` props, typically when used outside of Gatsby's `wrapPageElement` API or when the props are not correctly spread.fixEnsure you are passing `location={props.location}` and `action={props.action}` directly to the `ScrollManager` within your `gatsby-browser.js` `wrapPageElement` export. -
error glob@11.0.3: The engine "node" is incompatible with this module. Expected version "20 || >=22". Got "18.6.0"
cause This error, often seen during `npm install` or `yarn install`, indicates a mismatch between your Node.js version and Gatsby's (or its dependencies') expected Node.js version range.fixUpgrade your Node.js version to one compatible with Gatsby v5 (e.g., Node.js 20 or 22). Use `nvm install 20 && nvm use 20` or similar version management commands. -
Component(...): Nothing was returned from render. This usually means a return statement is missing or an undefined is unexpectedly returned.
cause This React error can occur if the `ScrollManager` component or its parent `wrapPageElement` function does not explicitly return JSX, leading to an undefined return value for the component.fixVerify that your `wrapPageElement` function in `gatsby-browser.js` always returns the `ScrollManager` component with `element` as its child, like `return (<ScrollManager>{element}</ScrollManager>);`
Warnings
- breaking This package underwent significant internal changes to align with Gatsby's adoption of `@reach/router`. Direct usage with `react-router-dom` (versions v5, v6, or earlier) will not function correctly due to fundamental API and architectural differences in routing libraries.
- breaking Gatsby, and by extension this plugin, has specific Node.js version requirements. Using unsupported Node.js versions (e.g., <18.0.0 or >=26.0.0) can lead to installation failures, build errors, or unexpected runtime behavior.
- gotcha Scroll restoration provided by this plugin might not work optimally or consistently for pages that dynamically load content after the initial render, or for components that manually manipulate scroll position. The scroll point is determined early in the navigation lifecycle.
- gotcha Enabling multiple scroll management solutions simultaneously (e.g., another Gatsby plugin for scroll, custom `useEffect` hooks, or conflicting browser settings) can lead to unpredictable, 'jumpy,' or incorrect scroll positions.
Install
-
npm install gatsby-react-router-scroll -
yarn add gatsby-react-router-scroll -
pnpm add gatsby-react-router-scroll
Imports
- ScrollManager
const ScrollManager = require('gatsby-react-router-scroll');import { ScrollManager } from 'gatsby-react-router-scroll'; - wrapPageElement
export const wrapPageElement = ({ element, props }) => { /* ... */ };
Quickstart
import React from 'react';
import { ScrollManager } from 'gatsby-react-router-scroll';
// In your gatsby-browser.js file
export const wrapPageElement = ({ element, props }) => {
const { location, action } = props;
return (
<ScrollManager
location={location}
action={action}
autoElementScroll={true} // Automatically scroll to the top of the page on route change
timeout={100} // Optional: Adjust the timeout for scroll restoration (ms)
>
{element}
</ScrollManager>
);
};
// Optional: For server-side rendering (SSR), you can also export from gatsby-ssr.js
// export { wrapPageElement } from './gatsby-browser';