Created
May 4, 2026 06:47
-
-
Save cgarrovillo/94ee01afe1bdb07d0fb835cd9580e583 to your computer and use it in GitHub Desktop.
Performative Scroll Restoration 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| "use client"; | |
| import { usePathname } from "next/navigation"; | |
| import { useEffect, useLayoutEffect, useRef } from "react"; | |
| const KEY_PREFIX = "scroll-"; | |
| const useIsoLayoutEffect = | |
| typeof window !== "undefined" ? useLayoutEffect : useEffect; | |
| export function ScrollRestoration() { | |
| const pathname = usePathname(); | |
| const pathnameRef = useRef(pathname); | |
| useIsoLayoutEffect(() => { | |
| pathnameRef.current = pathname; | |
| const saved = sessionStorage.getItem(KEY_PREFIX + pathname); | |
| if (saved !== null) { | |
| window.scrollTo({ | |
| top: parseInt(saved, 10), | |
| left: 0, | |
| behavior: "instant", | |
| }); | |
| } | |
| }, [pathname]); | |
| useEffect(() => { | |
| const save = () => { | |
| sessionStorage.setItem( | |
| KEY_PREFIX + pathnameRef.current, | |
| String(window.scrollY), | |
| ); | |
| }; | |
| const onClickCapture = (event: MouseEvent) => { | |
| const link = (event.target as Element | null)?.closest?.("a[href]"); | |
| if (link) save(); | |
| }; | |
| const onPageHide = () => save(); | |
| document.addEventListener("click", onClickCapture, true); | |
| window.addEventListener("pagehide", onPageHide); | |
| return () => { | |
| document.removeEventListener("click", onClickCapture, true); | |
| window.removeEventListener("pagehide", onPageHide); | |
| }; | |
| }, []); | |
| return null; | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment