#How to restore scroll position when reload?

1 messages · Page 1 of 1 (latest)

clear sapphire
#

How to restore scroll position when reload?

weak warrenBOT
#

Hi @clear sapphire. I'm kapa.ai, your friendly support bot. I will try to answer your question by searching through the knowledge base. :wave:

#

To restore the scroll position when reloading a page in a Next.js application, you can use a custom hook to save the scroll position before the page unloads and then restore it when the page loads again. Below is an example of how you can achieve this using the usePersistentScroll hook from the knowledge sources:

// utils/usePersistentScroll.tsx
import { usePathname, useRouter, useSearchParams } from 'next/navigation'
import { useCallback, useEffect } from 'react'

export const usePersistentScroll = () => {
  const router = useRouter()
  const searchParams = useSearchParams()
  const pathname = usePathname()

  useEffect(() => {
    const persistentScroll = localStorage.getItem('persistentScroll')
    if (persistentScroll === null) return

    window.scrollTo({ top: Number(persistentScroll) })

    if (Number(persistentScroll) === window.scrollY) localStorage.removeItem('persistentScroll')
  }, [searchParams])

  const saveScrollPosition = useCallback(() => {
    localStorage.setItem('persistentScroll', window.scrollY.toString())
  }, [])

  const setSearchParam = useCallback(
    (key: string, value: string) => {
      const currentParams = searchParams?.toString()
      const params = new URLSearchParams(currentParams)

      params.set(key, value)

      if (currentParams === params.toString()) return

      saveScrollPosition()
      router.push(`${pathname}?${params.toString()}`)
    },
    [searchParams, pathname, router, saveScrollPosition],
  )

  return { setSearchParam, saveScrollPosition }
}

Usage in a component:

// components/ExampleComponent.tsx
import { usePersistentScroll } from '@/utils/usePersistentScroll'

export default function ExampleComponent() {
  const { setSearchParam, saveScrollPosition } = usePersistentScroll()
#

return (
<button
onClick={() => {
setSearchParam('exampleParam', '9999') // or 'saveScrollPosition' for persisting scrollY pos only
}}
>
Update search params
</button>
)
}


This hook saves the scroll position to `localStorage` before the page unloads and restores it when the page loads again. You can call `saveScrollPosition` whenever you need to save the current scroll position, such as before navigating to a new page or updating search parameters.

For more details, you can refer to the original discussion in the **Github Issue** (<https://github.com/vercel/next.js/issues/49087>).
----------------------
Note: you can ask me a follow up question by @ mentioning me again :speech_balloon:
----------------------