All hooks / Storage and URL

useLocalStorage

368 B minified and brotliedSourceMarkdown✓ Works in all modern browsers

State that persists in localStorage as JSON, stays in sync across components and browser tabs, and is safe to server-render.

Renders serverValue on the server and during hydration, then switches to the stored value with no hydration mismatch. Missing or unparseable stored values also read as serverValue. Setting undefined removes the key.

Values go through JSON: a Date comes back as a string, and Map, Set, Infinity, and undefined inside objects don't survive. Store plain data. Writes made directly with localStorage in the same tab aren't seen; go through the setter.

Import

import { useLocalStorage } from '@vincent.ri/react-tils'
// or only this hook
import { useLocalStorage } from '@vincent.ri/react-tils/useLocalStorage'

Usage

const [theme, setTheme] = useLocalStorage<'light' | 'dark'>('theme', 'light')
setTheme('dark')

const [count, setCount] = useLocalStorage('count', 0)
setCount((c) => c + 1)

Live demo

Reload: both stay. Open a second tab: local syncs, session does not.

local 0
session 0

When to use it

User preferences, drafts, or UI state should survive a reload or be shared between tabs (theme, sidebar open, last tab).

When not to

The data is sensitive (tokens, personal data). Any script on the page can read localStorage. Also not for large data (5 MB limit, blocks the main thread); use IndexedDB. Not for server-needed state; use cookies.

API

function useLocalStorage<T>(key: string, serverValue: T): [T, SetValue<T>]
ParameterDescription
keyThe localStorage key.
serverValueValue on the server, during hydration, and when nothing valid is stored. Pass a primitive or a constant, so the setter stays stable.

Returns [value, setValue], like useState. setValue accepts a value or an updater. If storage is full or blocked, the value still updates for this page session but isn't saved.

Browser support

UsesChromeEdgeFirefoxSafariChrome AndroidSafari iOS
localStorageWidely available4+12+3.5+4+18+3.2+
storage eventWidely available1+15+45+4+18+4+

First version with support, from MDN's compatibility data (web-features 3.42.0, @mdn/browser-compat-data 8.1.5).

Coming from another library?

Other libraries call this useLocalStorageState.