diff --git a/e2e-tests/production-runtime/cypress/integration/scroll-behavior.js b/e2e-tests/production-runtime/cypress/integration/scroll-behavior.js index e1f135df5169d..e62a769a2132e 100644 --- a/e2e-tests/production-runtime/cypress/integration/scroll-behavior.js +++ b/e2e-tests/production-runtime/cypress/integration/scroll-behavior.js @@ -48,7 +48,7 @@ describe(`Scroll behaviour`, () => { cy.go(`forward`).waitForRouteChange() cy.window().then(updatedWindow => { - expect(updatedWindow.scrollY).not.to.eq(idScrollY) + expect(updatedWindow.scrollY).to.eq(idScrollY) }) }) }) diff --git a/packages/gatsby-react-router-scroll/src/scroll-handler.tsx b/packages/gatsby-react-router-scroll/src/scroll-handler.tsx index e7289346343e0..b547308b84810 100644 --- a/packages/gatsby-react-router-scroll/src/scroll-handler.tsx +++ b/packages/gatsby-react-router-scroll/src/scroll-handler.tsx @@ -61,7 +61,16 @@ export class ScrollHandler extends React.Component< scrollPosition = this._stateStorage.read(this.props.location, key) } - if (hash && scrollPosition === 0) { + /** There are two pieces of state: the browser url and + * history state which keeps track of scroll position + * Native behaviour prescribes that we ought to restore scroll position + * when a user navigates back in their browser (this is the `POP` action) + * Currently, reach router has a bug that prevents this at https://github.com/reach/router/issues/228 + * So we _always_ stick to the url as a source of truth — if the url + * contains a hash, we scroll to it + */ + + if (hash) { this.scrollToHash(decodeURI(hash), prevProps) } else { this.windowScroll(scrollPosition, prevProps)