#How to restore scroll position when reload or redirect back/forward?
1 messages · Page 1 of 1 (latest)
To restore the scroll position when reloading or navigating back/forward in a Next.js application, you can leverage the built-in features of the App Router and Router Cache. Here are the steps and considerations based on the provided knowledge sources:
Using App Router with Router Cache
Next.js maintains the scroll position for backward and forward navigation by default and reuses route segments in the Router Cache (https://nextjs.org/docs/app/building-your-application/caching#router-cache). This ensures that the scroll position is restored correctly when navigating back or forward.
Disabling Scroll Restoration
If you want to disable the default scroll restoration behavior, you can pass scroll: false to router.push() or router.replace(). Here is an example:
'use client'
import { useRouter } from 'next/navigation'
export default function Page() {
const router = useRouter()
return (
<button
type="button"
onClick={() => router.push('/dashboard', { scroll: false })}
>
Dashboard
</button>
)
}
Source (https://nextjs.org/docs/app/api-reference/functions/use-router#disabling-scroll-restoration)
Custom Scroll Restoration
If you need a custom solution to persist and restore the scroll position, you can use a combination of local storage and event listeners. Here is an example of how you can implement this:
import { useRouter } from 'next/router'
import { useEffect, useCallback } from 'react'
export const usePersistentScroll = () => {
const router = useRouter()
useEffect(() => {
const persistentScroll = localStorage.getItem('persistentScroll')
if (persistentScroll === null) return
window.scrollTo({ top: Number(persistentScroll) })
if (Number(persistentScroll) === window.scrollY) localStorage.removeItem('persistentScroll')
}, [router.asPath])
const saveScrollPosition = useCallback(() => {
localStorage.setItem('persistentScroll', window.scrollY.toString())
}, [])
const setSearchParam = useCallback(
(key: string, value: string) => {
const currentParams = new URLSearchParams(window.location.search)
currentParams.set(key, value)
saveScrollPosition()
router.push(`${window.location.pathname}?${currentParams.toString()}`)
},
[router, saveScrollPosition],
)
return { setSearchParam, saveScrollPosition }
}
**Source** (<https://github.com/vercel/next.js/issues/49087>)
### Known Issues and Considerations
1. **Large Pages**: Scroll restoration might not work correctly for very large pages. This issue has been reported and can be reproduced by creating a large page and navigating back to it. **Source** (<https://github.com/vercel/next.js/issues/37893>)
2. **iOS Safari**: There are known issues with scroll restoration on iOS Safari, especially when using the back button after a quick upward swipe. **Source** (<https://github.com/vercel/next.js/issues/53777>)
3. **App Router**: Ensure that the `ACTION_RESTORE` event in the app-router contains the necessary information related to `focusAndScrollRef`. **Source** (<https://github.com/vercel/next.js/issues/58899>)
By following these guidelines and using the provided code examples, you should be able to manage scroll restoration effectively in your Next.js application.
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------
@formal sequoia kapa.ai is still learning and improving, please let us know how it did by reacting below