@lonli-lokli/scroll-restoration
Version:
A lightweight, framework-agnostic scroll restoration solution for React applications.
239 lines (189 loc) • 5.84 kB
Markdown
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.
- 🔄 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
```bash
npm install react-scroll-restoration
yarn add react-scroll-restoration
pnpm add react-scroll-restoration
```
```tsx
import { ScrollRestoration } from 'react-scroll-restoration';
function App() {
return (
<>
<ScrollRestoration />
{/* Your application content */}
</>
);
}
```
```tsx
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 */}
</>
);
}
```
```tsx
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 */}
</>
);
}
```
```tsx
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;
```
```tsx
function LongList() {
return (
<div
className="overflow-auto h-80"
data-scroll-restoration-id="user-comments"
>
{/* Long list content */}
</div>
);
}
```
```tsx
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>
);
}
```
The main hook for enabling scroll restoration.
| Option | Type | Description |
|--------|------|-------------|
| `getKey` | `(location: Location) => string` | Function to generate a unique key for a location |
| `scrollBehavior` | `'auto' \| 'smooth'` | Scroll behavior when restoring position |
| `getCurrentLocation` | `() => Location` | Function to get current location |
| `navigationListener` | `(onNavigate: (location: Location) => void) => () => void` | Function to listen for location changes |
A component wrapper for `useScrollRestoration` that returns `null`.
```tsx
<ScrollRestoration
getKey={(location) => location.pathname}
scrollBehavior="smooth"
/>
```
A hook for retrieving stored scroll positions for specific elements.
| Option | Type | Description |
|--------|------|-------------|
| `id` | `string` | ID to use with `data-scroll-restoration-id` attribute |
| `getElement` | `() => Element \| null \| undefined` | Function to get the element reference |
| `getKey` | `(location: Location) => string` | Function to generate a unique key for a location |
| `getCurrentLocation` | `() => Location` | Function to get current location |
The library works in all modern browsers that support these APIs:
- `sessionStorage`
- `window.history`
- `MutationObserver`
This library is written in TypeScript and provides type definitions out of the box.
MIT