-
SummaryI'm not sure why Next takes over scroll position on client route changes. The expected behavior for most apps/websites when clicking a link is to scroll to the top (since that's how the native web behaves). The exception being when the linking to an ID (like /page#somewhere-down-the-page). But Next.js has a different logic. For example, when linking to a page within a nested layout, instead of the user arriving at the top of the page as they'd expect, they are scrolled down to the point that the layout begins (the position being lower depending on how much vertical content in the parents). I was able to work around this by wrapping the children of the nested layout with a HOC that scrolls to the top on mount. This feels a big ugly and unnecessary, but it works: function ForceScrollToTop({ children }: { children: ReactNode }) {
useEffect(() => {
document.scrollingElement?.scrollTo(0, 0);
}, []);
return <>{children}</>;
}However, after upgrading from v13.3.1, there were new changes to the scroll behavior. Now, if a user clicks a link lower down a page, Next's router remembers that scroll position when linking back to that page. This may be well and good when you hit the back button (it might be helpful to return to the same position you were just at). But when linking to that page from another page, from anywhere in the app, it remembers and returns to the last scroll position you were at, even if it's no longer relevant. A solution I found for this won't work with the app directory, since router events have been removed. So now I'm not sure what to do to ensure the user is always scrolled to the top of the page on route changes. Just realized as I'm writing I can try to make my own component. But I'm not sure if doing a manual router.push() would bypass the scrolling behavior. Here's an example of the first problem (haven't published since the upgrade), If you click on "work" then any of the projects, you'll notice that the next page is quickly scrolled to the top (because of my HOC, otherwise, you'd arrive at a scroll position of the layout which starts below the header). But it's more problematic since the recent Next update. If you click on Home from the second page, right now (pre upgrade), it takes you to the top of Home as I think you'd expect. But after the upgrade, clicking the Home link takes you there but scrolled down to the position where you last left it. To me this makes no sense. When I explicitly click on a link, I expect to be taken to the top of the page. Additional informationNo response ExampleNo response |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments
-
|
Pretty bizarre change to make be default. I'm surprised no one is talking about it, and everyone is just "cool" with this behavior. If something has worked the same for the past 30 years, and 99% of websites have the user start at the top of the page when clicking a link, why change it? Especially by default? |
Beta Was this translation helpful? Give feedback.
-
|
Looks like they fixed it sometime in the last week! After updating, I was able to remove the hacks and the router is scrolling to top as it should. There were several related bugs on the tracker, I'd just posted this here since the maintainers didn't seem to be responding and I figured they had their own logic about it. |
Beta Was this translation helpful? Give feedback.
-
|
I found a solution, in the root layout add data-scroll-behavior="smooth" and in the css: |
Beta Was this translation helpful? Give feedback.
Looks like they fixed it sometime in the last week! After updating, I was able to remove the hacks and the router is scrolling to top as it should.
There were several related bugs on the tracker, I'd just posted this here since the maintainers didn't seem to be responding and I figured they had their own logic about it.