Scroll restoration happens too early before the page gets rendered after hitting browser back button
Problem
- [x] I have searched the issues of this repository and believe that this is not a duplicate. After transiting from one page to another page via next `<Link />`, if user clicks the back button and the previous page has `getInitialProps` method that takes some time to finish, the scroll position of the previous will be restored before the previous pages gets rendered. Demo source code can be found here After clicking back button, the "go back" text should still be visible (not scroll down to previous position) until the previous page gets rendered
Unverified for your environment
Select your OS to check compatibility.
1 Fix
Delay Scroll Restoration Until Page Render Completes
The issue arises because the scroll restoration occurs immediately after the back button is clicked, before the previous page's content has fully rendered. This is due to the default behavior of the browser's scroll restoration mechanism, which does not account for the asynchronous nature of data fetching in Next.js, particularly when using `getInitialProps` that may take time to resolve.
Awaiting Verification
Be the first to verify this fix
- 1
Disable Automatic Scroll Restoration
Prevent the browser from automatically restoring the scroll position when navigating back. This can be achieved by setting the `scrollRestoration` property of the history API to 'manual'.
javascriptwindow.history.scrollRestoration = 'manual'; - 2
Implement Custom Scroll Restoration Logic
Create a custom scroll restoration mechanism that only restores the scroll position after the page has fully rendered. This can be done by using a state variable to track when the page is ready.
javascriptconst [isPageReady, setIsPageReady] = useState(false); useEffect(() => { if (isPageReady) { window.scrollTo(0, savedScrollPosition); } }, [isPageReady]); - 3
Set Scroll Position After Data Fetching
After the `getInitialProps` method completes, set the `isPageReady` state to true, indicating that the page has rendered and it's safe to restore the scroll position.
javascriptstatic async getInitialProps() { const data = await fetchData(); this.setState({ isPageReady: true }); return { data }; } - 4
Test Scroll Behavior
Perform thorough testing by navigating back and forth between pages to ensure that the scroll position is only restored after the page has rendered completely. Check for any edge cases where the content may load slowly.
javascriptconsole.log('Testing scroll restoration behavior...');
Validation
Confirm the fix by navigating back to the previous page and ensuring that the scroll position does not change until the page content is fully rendered. The 'go back' text should remain visible until the rendering is complete.
Sign in to verify this fix
Environment
Submitted by
Alex Chen
2450 rep