useLocalStorage

Persist state in localStorage with automatic synchronization across tabs, type-safe storage and retrieval, and fallback value support. Handles JSON serialization and parsing automatically.

Live Demo

Stored Value:

default value

Implementation

export function useLocalStorage<T>(key: string, initialValue: T) {
  const [storedValue, setStoredValue] = useState<T>(() => {
    if (typeof window === "undefined") return initialValue;
    try {
      const item = window.localStorage.getItem(key);
      return item ? JSON.parse(item) : initialValue;
    } catch (error) {
      console.error(error);
      return initialValue;
    }
  });

  const setValue = (value: T | ((val: T) => T)) => {
    try {
      const valueToStore = value instanceof Function ? value(storedValue) : value;
      setStoredValue(valueToStore);
      if (typeof window !== "undefined") {
        window.localStorage.setItem(key, JSON.stringify(valueToStore));
      }
    } catch (error) {
      console.error(error);
    }
  };

  return [storedValue, setValue] as const;
}

Usage

const [value, setValue] = useLocalStorage("storage-key", initialValue);

// Use it like useState
setValue("new value");

// Or with a function
setValue(prev => prev + 1);

Important Notes

Server-Side Rendering (SSR) Limitations

This hook is designed to handle SSR environments safely. Since localStorage is only available in the browser:

  • During SSR, the hook will return the initialValue
  • localStorage operations are only performed on the client-side
  • The hook includes checks for window object availability to prevent SSR errors