Skip to content

Instantly share code, notes, and snippets.

@Jak-Ch-ll
Last active April 29, 2023 17:47
Show Gist options
  • Save Jak-Ch-ll/12d3ac96c1562e85c508dd40d309be45 to your computer and use it in GitHub Desktop.
Save Jak-Ch-ll/12d3ac96c1562e85c508dd40d309be45 to your computer and use it in GitHub Desktop.
Next.js - Preserve Scroll History
import { useRouter } from "next/router"
import { useEffect, useRef } from "react"
export const usePreserveScroll = () => {
const router = useRouter()
const scrollPositions = useRef<{ [url: string]: number }>({})
const isBack = useRef(false)
useEffect(() => {
router.beforePopState(() => {
isBack.current = true
return true
})
const onRouteChangeStart = () => {
const url = router.pathname
scrollPositions.current[url] = window.scrollY
}
const onRouteChangeComplete = (url: any) => {
if (isBack.current && scrollPositions.current[url]) {
window.scroll({
top: scrollPositions.current[url],
behavior: "auto",
})
}
isBack.current = false
}
router.events.on("routeChangeStart", onRouteChangeStart)
router.events.on("routeChangeComplete", onRouteChangeComplete)
return () => {
router.events.off("routeChangeStart", onRouteChangeStart)
router.events.off("routeChangeComplete", onRouteChangeComplete)
}
}, [router])
}
@Jak-Ch-ll
Copy link
Author

Jak-Ch-ll commented Jun 21, 2021

This custom hook can be imported and called in _app.tsx to enable saving and restoring the scroll position of pages on using the back-button in the browser.

You can find a full explanation in my medium article: Next.js - Preserve Scroll History

@KirillTregubov
Copy link

I wasn't happy with the way scrolling was handled on my Next.js site, and I went through a few different solutions before landing on yours. Cheers! 🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment