Join our Discord Community

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.

Loading component...

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

Loading component...

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

ParameterTypeDefaultDescription
keystringrequiredStorage key for the sessionStorage item
initialValueT | (() => T)requiredInitial value or function returning initial value
optionsUseSessionStorageOptions<T>{}Configuration options for serialization

UseSessionStorageOptions

PropertyTypeDefaultDescription
serializer(value: T) => stringJSON.stringifyCustom function to serialize values before storage
deserializer(value: string) => TJSON.parseCustom function to deserialize values from storage
initializeWithValuebooleantrueWhether to initialize with stored value immediately

Return Value

Returns a tuple with three elements:

IndexTypeDescription
[0]TCurrent stored value
[1]Dispatch<SetStateAction<T>>Function to update the stored value
[2]() => voidFunction 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)