useSessionStorage
Custom hook that uses the sessionStorage API to persist state across page reloads with serialization and cross-tab synchronization. Perfect for React applications requiring temporary state persistence with Next.js integration and TypeScript support.
Installation
npx shadcn@latest add https://www.shadcn.io/registry/use-session-storage.json
npx shadcn@latest add https://www.shadcn.io/registry/use-session-storage.json
pnpm dlx shadcn@latest add https://www.shadcn.io/registry/use-session-storage.json
bunx shadcn@latest add https://www.shadcn.io/registry/use-session-storage.json
Features
- Session persistence maintaining state across page reloads within the same browser tab
- Type-safe storage with full TypeScript support for complex objects and primitives
- Custom serialization allowing custom serializer and deserializer functions
- Cross-tab synchronization updating state when sessionStorage changes in other components
- SSR compatibility with proper server-side rendering support and initialization options
- Error handling with graceful fallbacks and console warnings for debugging
- shadcn/ui integration ideal for form data, user preferences, and temporary state
Examples
Advanced Object Storage
Demonstrates complex object storage, custom serialization, and multiple storage instances.
Use Cases
This free open source React component works well for:
- Form persistence - Save form data across page reloads to prevent data loss with Next.js
- User preferences - Store temporary UI settings and theme choices using TypeScript
- Shopping cart - Maintain cart state during browsing session with shadcn/ui components
- Draft content - Preserve draft articles, comments, or messages using Tailwind CSS
- Multi-step wizards - Save progress through complex forms and workflows
API Reference
useSessionStorage
Parameter | Type | Default | Description |
---|---|---|---|
key | string | required | Storage key for the sessionStorage item |
initialValue | T | (() => T) | required | Initial value or function returning initial value |
options | UseSessionStorageOptions<T> | {} | Configuration options for serialization |
UseSessionStorageOptions
Property | Type | Default | Description |
---|---|---|---|
serializer | (value: T) => string | JSON.stringify | Custom function to serialize values before storage |
deserializer | (value: string) => T | JSON.parse | Custom function to deserialize values from storage |
initializeWithValue | boolean | true | Whether to initialize with stored value immediately |
Return Value
Returns a tuple with three elements:
Index | Type | Description |
---|---|---|
[0] | T | Current stored value |
[1] | Dispatch<SetStateAction<T>> | Function to update the stored value |
[2] | () => void | Function to remove the item from storage |
Usage Patterns
Basic Value Storage
import { useSessionStorage } from '@repo/use-session-storage';
function Counter() {
const [count, setCount, removeCount] = useSessionStorage('count', 0);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setCount(c => c + 1)}>Increment</button>
<button onClick={removeCount}>Reset</button>
</div>
);
}
Complex Object Storage
interface UserSettings {
theme: 'light' | 'dark';
notifications: boolean;
}
const [settings, setSettings, removeSettings] = useSessionStorage<UserSettings>(
'user-settings',
{ theme: 'light', notifications: true }
);
// Update nested properties
setSettings(prev => ({
...prev,
theme: prev.theme === 'light' ? 'dark' : 'light'
}));
Custom Serialization
const dateSerializer = (date: Date) => date.toISOString();
const dateDeserializer = (value: string) => new Date(value);
const [lastVisit, setLastVisit] = useSessionStorage(
'last-visit',
new Date(),
{
serializer: dateSerializer,
deserializer: dateDeserializer
}
);
SSR-Safe Usage
const [data, setData] = useSessionStorage(
'data',
null,
{ initializeWithValue: false }
);
// data will be null during SSR, then hydrate with stored value
Functional Updates
const [items, setItems] = useSessionStorage<string[]>('items', []);
// Add item
setItems(prev => [...prev, newItem]);
// Remove item
setItems(prev => prev.filter(item => item !== targetItem));
// Clear all
setItems([]);
Implementation Notes
- sessionStorage data persists only within the same browser tab (unlike localStorage)
- Data is automatically cleared when the tab is closed or browser is restarted
- Hook automatically synchronizes state across multiple hook instances with the same key
- Uses custom event dispatching for cross-component state synchronization
- Handles JSON serialization errors gracefully with fallback to initial values
- SSR-safe with proper hydration handling when
initializeWithValue
is false - Event listeners are properly cleaned up to prevent memory leaks
- Compatible with all modern browsers that support sessionStorage API
- Storage quotas apply (typically 5-10MB per origin, varies by browser)
useScrollLock
React hook that locks and unlocks scroll on target elements with width reflow prevention and automatic cleanup.
useStep
Custom React hook that manages and navigates between steps in a multi-step process. Perfect for wizards, onboarding flows, and step-by-step forms with Next.js integration and TypeScript support.