DEV Community

Matteo Mazzarolo
Matteo Mazzarolo

Posted on • Originally published at mmazzarolo.com on

8

Scroll restoration in Next.js

While working on Remotebear, I recently discovered that Next.js doesn’t handle scroll restoration automatically. So, for example, if you navigate back to a previous page of your app, Next.js will always show it scrolled to the top, regardless of the scroll position it had when you left it.

Experimental scroll restoration flag

Luckily, Next.js has an experimental scrollRestoration flag that you can enable to automatically restore the scroll positions.

You can enable it in your next.config.js file this way:

module.exports = {
  experimental: {
    scrollRestoration: true,
  },
};
Enter fullscreen mode Exit fullscreen mode

next-router-scroll

For my use case, this solution is working fine, but there are some cases where you need to take control of how your application scroll is handled; namely, you may want to restore scroll when the user is navigating within your application pages, but you need to do extra work before or after the page has changed, either by using some sort of page transition or any other feature.

In these cases, I’d suggest you give @moxy/next-router-scroll a try: This package is built on top of scroll-behavior and it actively listens to Next.js router events, writing the scroll values associated with the current location in the Session Storage and reading these values whenever updateScroll() is called.

Completely disabling scroll restoration

There’s one inconsistency I noticed around not making scroll restoration work automatically in Next.js: by default, scroll restoration doesn’t work when the navigation logic is being handled by JavaScript, but it works fine when it’s handled by the browser (e.g.: on a full-refresh or while navigating whit JavaScript disabled).

So, in the rare occasions where you want to fully disable scroll restoration, remember to add this snippet to the <head> of your project:

import Head from "next/head";

export default function ScrollRestorationDisabler() {
  return (
    <Head>
      {/* Tell the browser to never restore the scroll position on load */}
      <script
        dangerouslySetInnerHTML={{
          __html: `history.scrollRestoration = "manual"`,
        }}
      />
    </Head>
  );
}
Enter fullscreen mode Exit fullscreen mode

SurveyJS custom survey software

Build Your Own Forms without Manual Coding

SurveyJS UI libraries let you build a JSON-based form management system that integrates with any backend, giving you full control over your data with no user limits. Includes support for custom question types, skip logic, an integrated CSS editor, PDF export, real-time analytics, and more.

Learn more

Top comments (6)

Collapse
 
hayyaun profile image
Hayyan Hami

Thank you!At first it was working only with hashtag navigation, but then I realized that my main scrolling element is not the body tag. Now it's all working properly.

Collapse
 
ongkay profile image
ongkay

how use it in nextjs 13?

Collapse
 
azizc0der_66 profile image
Azizxo'ja Saidrahmonov

+

Collapse
 
endrureza profile image
Endru Reza

hey nice find dude. thanks, i need this one too

Collapse
 
sinanyilmaz profile image
Sinan Yilmaz • Edited

This ist actually not true in my experience. The commit you shared above is also over 1 year old. On Static pages the scroll restoration works without any configuration.

Collapse
 
thanhtutzaw profile image
ThanHtutZaw

Your static pages mean Only HTML ,CSS and Javascript ?

The best way to debug slow web pages cover image

The best way to debug slow web pages

Tools like Page Speed Insights and Google Lighthouse are great for providing advice for front end performance issues. But what these tools can’t do, is evaluate performance across your entire stack of distributed services and applications.

Watch video