Browser API shouldUpdateScroll logic not being respected on pop state route transitions
See original GitHub issueDescription
This is follow up issue to #27349 — that issue has been closed but I’m experiencing a second issue preventing me from orchestrating smooth page transitions. The issue of getSavedScrollPosition returning a single value rather than x, y coordinate array has been fixed and merged (https://github.com/gatsbyjs/gatsby/pull/27384). Console.logging the saved scroll position now returns the expected [x, y] coordinate array, which is great.
Now I’m experiencing an issue my original demos didn’t show: when navigating back using the browser back button from one page to the previous (when both pages have scrollable body content), the shouldUpdateScroll setTimeout seems to be ignored and scroll restoration applied immediately, disrupting the smooth effect of the page transition. This functionality worked correctly in previous versions of Gatsby (including v 2.19.43 as shown in my working comparison demo below).
// gatsby-browser.js
export const shouldUpdateScroll = ({
routerProps: { location },
getSavedScrollPosition,
}) => {
if (location.action === "PUSH") {
window.setTimeout(() => window.scrollTo(0, 0), 600)
} else {
const savedPosition = getSavedScrollPosition(location)
window.setTimeout(
() => window.scrollTo(...(savedPosition || [0, 0])),
600
)
}
return false
}
Steps to reproduce
Demonstration of the issue: https://fix-test--gatsby-scroll-restoration-issue.netlify.app/.
You can see the issue when you scroll to the bottom of page 1, click the link to page 2 and then hit the browser back button. You will see an immediate scroll position jump that disrupts the animated fade transition, but then page 1 is restored at the correct scroll position. It seems the exiting page is immediately scrolled to the saved scroll position of the page that has not yet entered.
Demo repo: https://github.com/blimpmason/gatsby-scroll-restoration-issue/tree/fix-test
Expected result
Original working comparison repo has been updated with the same page content as fix test branch above (uses Gatsby v2.19.43): https://gatsby-scroll-restoration-issue-comparison.netlify.app/
This shows that the scroll restoration does not occur until the setTimeout has elapsed per the shouldUpdateScroll logic in gatsby-browser.js.
Working comparison demo repo: https://github.com/blimpmason/gatsby-scroll-restoration-issue-comparison
Actual result
The restored scroll position is immediately applied to the exiting page before the setTimeout has elapsed, causing a janky page transition.
It’s worth noting that the setTimeout is respected on Push state transitions.
Environment
System:
OS: macOS 10.15.7
CPU: (16) x64 Intel(R) Core(TM) i9-9980HK CPU @ 2.40GHz
Shell: 3.2.57 - /bin/bash
Binaries:
Node: 14.4.0 - ~/.nvm/versions/node/v14.4.0/bin/node
Yarn: 1.22.4 - /usr/local/bin/yarn
npm: 6.14.5 - ~/.nvm/versions/node/v14.4.0/bin/npm
Languages:
Python: 2.7.16 - /usr/bin/python
Browsers:
Chrome: 87.0.4280.88
Firefox: 83.0
Safari: 14.0.1
npmPackages:
gatsby: ^2.29.0-next.1 => 2.24.72
gatsby-image: ^2.4.20 => 2.4.20
gatsby-plugin-layout: ^1.3.13 => 1.3.13
gatsby-plugin-manifest: ^2.4.33 => 2.4.33
gatsby-plugin-offline: ^3.2.30 => 3.2.30
gatsby-plugin-react-helmet: ^3.3.12 => 3.3.12
gatsby-plugin-sharp: ^2.6.38 => 2.6.38
gatsby-source-filesystem: ^2.3.32 => 2.3.32
gatsby-transformer-sharp: ^2.5.16 => 2.5.16
npmGlobalPackages:
gatsby-cli: 2.12.80
gatsby: 2.25.3
Issue Analytics
- State:
- Created 3 years ago
- Comments:30 (9 by maintainers)
Top GitHub Comments
Not stale!
Not stale!