Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Select an option

  • Save cgarrovillo/94ee01afe1bdb07d0fb835cd9580e583 to your computer and use it in GitHub Desktop.

Select an option

Save cgarrovillo/94ee01afe1bdb07d0fb835cd9580e583 to your computer and use it in GitHub Desktop.
Performative Scroll Restoration 2026
"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