Prevent scroll preservation on jump links in Next.js

Next.js has enabled a feature where it remembers your scroll position when you return to a page and doesn't just scroll to top. It's sometimes helpful, but if you have jump links, it renders them useless as it scrolls to top or wherever you were last at.

If you add the following snippet to your layout, it will allow the jump links to work as intended while preserving scrollRestoration for every other instance. If you don't care for scrollRestoration at all, just remove the condition and set it to manual.

Loading...
useEffect(() => { const {hash} = window.location; if (hash.length > 0) { history.scrollRestoration = 'manual'; } else { history.scrollRestoration = 'auto'; } }, []);

If you have a fixed header, the following CSS snippet will also be of use to you:

Loading...
h1[id], h2[id], h3[id], h4[id] { scroll-margin-top: 5rem; }

For each heading that has an id attribute, apply a scroll margin. Adjust as needed.

Note: I'm using rehypejs/rehype-slug and rehypejs/rehype-autolink-headings to add ids and links to my content headings.

Published July 10, 2024