Scroll restoration fails intermittently on back navigation when using code-splitting (i.e. resolving components asynchronously). I've observed this both with browser-default scroll restoration and by forcing usage of Intertia's scroll restoration mechanism by adding the scroll-region attribute to my page's scrolling element.
I've already spent some time digging into this (and asked about it in the Discord awhile back) and from what I can tell, the issue is a race condition between when the component we're navigating back to finishes rendering and when the scroll restoration mechanism executes. It seems that when using async components, it is possible for the the browser/Inertia to attempt to restore the scroll position before the component has completely loaded and rendered. I've verified this by switching my app to use eager loading for component resolution - after that change, the scroll position is restored as expected on back navigations. I'm not sure if this issue appears with other frameworks as well, but I imagine it could since they are also using Vite.
The simplest solution I've found is wrapping the scrollTo() call and scrollTop/scrollLeft setters in the router in requestAnimationFrame or setTimeout(() => {...}, 0). I'm not sure if this is a fool-proof solution, but its worked so far in my testing. I'd be happy to submit a PR for whatever solution you think would be best.
Version:
@inertiajs/react
version: 1.0.14Describe the problem:
Scroll restoration fails intermittently on back navigation when using code-splitting (i.e. resolving components asynchronously). I've observed this both with browser-default scroll restoration and by forcing usage of Intertia's scroll restoration mechanism by adding the
scroll-region
attribute to my page's scrolling element.I've already spent some time digging into this (and asked about it in the Discord awhile back) and from what I can tell, the issue is a race condition between when the component we're navigating back to finishes rendering and when the scroll restoration mechanism executes. It seems that when using async components, it is possible for the the browser/Inertia to attempt to restore the scroll position before the component has completely loaded and rendered. I've verified this by switching my app to use eager loading for component resolution - after that change, the scroll position is restored as expected on back navigations. I'm not sure if this issue appears with other frameworks as well, but I imagine it could since they are also using Vite.
The simplest solution I've found is wrapping the
scrollTo()
call andscrollTop
/scrollLeft
setters in the router inrequestAnimationFrame
orsetTimeout(() => {...}, 0)
. I'm not sure if this is a fool-proof solution, but its worked so far in my testing. I'd be happy to submit a PR for whatever solution you think would be best.Steps to reproduce: