0.7.0 • Published 10 months ago

@lonli-lokli/scroll-restoration v0.7.0

Weekly downloads
-
License
MIT
Repository
github
Last release
10 months ago

React Scroll Restoration

A lightweight, framework-agnostic scroll restoration solution for React applications. This library helps preserve and restore scroll positions when navigating between pages, providing a smoother user experience.

Features

  • 🔄 Restore scroll positions when navigating back and forth
  • 📦 No router dependencies
  • 🧩 Compatible with any React routing solution
  • 📱 Works with nested scrollable elements
  • 🔍 Supports custom location key strategies
  • 🌊 Configurable scroll behavior
  • 🔌 Extensible navigation detection

Installation

npm install react-scroll-restoration
# or
yarn add react-scroll-restoration
# or
pnpm add react-scroll-restoration

Basic Usage

import { ScrollRestoration } from 'react-scroll-restoration';

function App() {
  return (
    <>
      <ScrollRestoration />
      {/* Your application content */}
    </>
  );
}

Advanced Usage

Custom Configuration

import { ScrollRestoration } from 'react-scroll-restoration';

function App() {
  return (
    <>
      <ScrollRestoration 
        // Use only pathname for identifying routes
        getKey={(location) => location.pathname}
        // Enable smooth scrolling
        scrollBehavior="smooth"
      />
      {/* Your application content */}
    </>
  );
}

With React Router

import { ScrollRestoration } from 'react-scroll-restoration';
import { useLocation, useNavigate } from 'react-router-dom';

function App() {
  const location = useLocation();
  
  return (
    <>
      <ScrollRestoration 
        // Use React Router's location
        getCurrentLocation={() => ({
          href: window.location.href,
          pathname: location.pathname,
          search: location.search,
          hash: location.hash,
          state: location.state,
        })}
        // Listen for React Router navigation
        navigationListener={(onNavigate) => {
          const unlisten = history.listen(() => {
            onNavigate(location);
          });
          return unlisten;
        }}
      />
      {/* Your application content */}
    </>
  );
}

With Next.js

import { ScrollRestoration } from 'react-scroll-restoration';
import { useRouter } from 'next/router';

function MyApp({ Component, pageProps }) {
  const router = useRouter();
  
  return (
    <>
      <ScrollRestoration 
        getKey={(location) => location.pathname}
        navigationListener={(onNavigate) => {
          const handleRouteChange = () => {
            onNavigate({
              pathname: router.pathname,
              search: router.query ? Object.entries(router.query)
                .map(([key, value]) => `${key}=${value}`)
                .join('&') : '',
              hash: window.location.hash,
              href: window.location.href,
              state: history.state,
            });
          };
          
          router.events.on('routeChangeComplete', handleRouteChange);
          
          return () => {
            router.events.off('routeChangeComplete', handleRouteChange);
          };
        }}
      />
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

Scrollable Elements

Using data attribute (recommended)

function LongList() {
  return (
    <div 
      className="overflow-auto h-80"
      data-scroll-restoration-id="user-comments"
    >
      {/* Long list content */}
    </div>
  );
}

Using imperative handle

import { useRef, useEffect } from 'react';
import { useElementScrollRestoration } from 'react-scroll-restoration';

function LongList() {
  const containerRef = useRef<HTMLDivElement>(null);
  
  // Get stored scroll position
  const scrollPosition = useElementScrollRestoration({
    getElement: () => containerRef.current,
  });
  
  // Apply stored scroll position on mount
  useEffect(() => {
    if (containerRef.current && scrollPosition) {
      containerRef.current.scrollLeft = scrollPosition.scrollX;
      containerRef.current.scrollTop = scrollPosition.scrollY;
    }
  }, [scrollPosition]);
  
  return (
    <div 
      ref={containerRef}
      className="overflow-auto h-80"
    >
      {/* Long list content */}
    </div>
  );
}

API Reference

useScrollRestoration(options?)

The main hook for enabling scroll restoration.

Options

OptionTypeDescription
getKey(location: Location) => stringFunction to generate a unique key for a location
scrollBehavior'auto' \| 'smooth'Scroll behavior when restoring position
getCurrentLocation() => LocationFunction to get current location
navigationListener(onNavigate: (location: Location) => void) => () => voidFunction to listen for location changes

ScrollRestoration Component

A component wrapper for useScrollRestoration that returns null.

<ScrollRestoration
  getKey={(location) => location.pathname}
  scrollBehavior="smooth"
/>

useElementScrollRestoration(options)

A hook for retrieving stored scroll positions for specific elements.

Options

OptionTypeDescription
idstringID to use with data-scroll-restoration-id attribute
getElement() => Element \| null \| undefinedFunction to get the element reference
getKey(location: Location) => stringFunction to generate a unique key for a location
getCurrentLocation() => LocationFunction to get current location

Browser Support

The library works in all modern browsers that support these APIs:

  • sessionStorage
  • window.history
  • MutationObserver

TypeScript Support

This library is written in TypeScript and provides type definitions out of the box.

License

MIT

1.0.0

10 months ago

0.14.0

10 months ago

0.12.0

10 months ago

0.13.0

10 months ago

0.11.0-0

10 months ago

0.11.0

10 months ago

0.10.0

10 months ago

0.8.0

10 months ago

0.7.0

10 months ago

0.6.0

10 months ago

0.5.0

10 months ago

0.4.0

10 months ago

0.3.0

10 months ago