Skip to main content

useScrollRestoration

When rendered inside a RouterProvider, will restore scroll positions on navigations.
import { useScrollRestoration } from "react-router";

function App() {
  useScrollRestoration();
  
  return <div>{/* Your app */}</div>;
}

Parameters

options
object
getKey
GetScrollRestorationKeyFunction
A function that returns a key to use for scroll restoration. This is useful for custom scroll restoration logic, such as using only the pathname so that subsequent navigations to prior paths will restore the scroll.Defaults to location.key.
useScrollRestoration({
  getKey: (location, matches) => {
    // Restore based on pathname only
    return location.pathname;
  },
});
storageKey
string
default:"\"react-router-scroll-positions\""
The key to use for storing scroll positions in sessionStorage.

Type Declaration

declare function useScrollRestoration(options?: {
  getKey?: GetScrollRestorationKeyFunction;
  storageKey?: string;
}): void;

type GetScrollRestorationKeyFunction = (
  location: Location,
  matches: UIMatch[]
) => string | null;

Deprecation Notice

This hook is deprecated in favor of the <ScrollRestoration> component. The component approach is preferred because:
  1. Better SSR support: The component can inject the necessary script for SSR scroll restoration
  2. Simpler API: No need to manually call the hook in your components
  3. Automatic setup: Just render the component and it works

Migration Guide

Before (using useScrollRestoration)

import { useScrollRestoration } from "react-router";

function Root() {
  useScrollRestoration();
  
  return (
    <html>
      <body>
        <Outlet />
        <Scripts />
      </body>
    </html>
  );
}

After (using ScrollRestoration component)

import { ScrollRestoration } from "react-router";

export default function Root() {
  return (
    <html>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}

Usage Examples (Legacy)

Basic Usage

import { useScrollRestoration } from "react-router";

function App() {
  useScrollRestoration();

  return (
    <div>
      <nav>{/* Navigation */}</nav>
      <main>{/* Content */}</main>
    </div>
  );
}

Custom Storage Key

import { useScrollRestoration } from "react-router";

function App() {
  useScrollRestoration({
    storageKey: "my-app-scroll-positions",
  });

  return <div>{/* App content */}</div>;
}

Pathname-Based Restoration

import { useScrollRestoration } from "react-router";

function App() {
  useScrollRestoration({
    getKey: (location, matches) => {
      // Restore scroll based only on pathname
      // This means going to /blog/post-1 will always
      // restore to the same position, regardless of how you got there
      return location.pathname;
    },
  });

  return <div>{/* App content */}</div>;
}

Route-Based Restoration

import { useScrollRestoration } from "react-router";

function App() {
  useScrollRestoration({
    getKey: (location, matches) => {
      // Restore based on the route ID
      const match = matches[matches.length - 1];
      return match?.route.id || location.key;
    },
  });

  return <div>{/* App content */}</div>;
}

Conditional Restoration

import { useScrollRestoration } from "react-router";

function App() {
  useScrollRestoration({
    getKey: (location, matches) => {
      // Don't restore scroll for certain paths
      const paths = ["/search", "/filter"];
      if (paths.some((path) => location.pathname.startsWith(path))) {
        return null; // Don't restore
      }
      return location.key;
    },
  });

  return <div>{/* App content */}</div>;
}

How It Works

The hook:
  1. Saves scroll positions to sessionStorage when navigating away from a page
  2. Restores scroll positions when navigating back to a previously visited page
  3. Uses location.key by default to track scroll positions for each history entry
  4. Allows customization via the getKey function for different restoration strategies

Alternatives

import { ScrollRestoration } from "react-router";

export default function Root() {
  return (
    <html>
      <body>
        <Outlet />
        <ScrollRestoration />
        <Scripts />
      </body>
    </html>
  );
}

Manual Scroll Management

import { useEffect } from "react";
import { useLocation } from "react-router";

function App() {
  const location = useLocation();

  useEffect(() => {
    // Custom scroll behavior
    window.scrollTo(0, 0);
  }, [location.pathname]);

  return <div>{/* App content */}</div>;
}
import { Link } from "react-router";

<Link to="/path" preventScrollReset>
  Don't reset scroll
</Link>

Notes

  • Deprecated: Use the <ScrollRestoration> component instead
  • Available in Framework and Data modes only
  • Must be used within a RouterProvider
  • Stores scroll positions in sessionStorage
  • The getKey function allows customizing which navigations restore scroll
  • Returning null from getKey prevents scroll restoration for that navigation

Build docs developers (and LLMs) love