URL-backed state
Persist state in a URL hash or query string.
Zustand · Type Alias
StateStorage is Zustand persist’s adapter type for custom persistence backends. Implement it when state should be stored somewhere other than the default localStorage-based setup.
StateStorage describes the storage adapter used by persist: an object supplying methods to read, write, and remove a named value. It can wrap browser storage or a custom backend; the documentation demonstrates URL-hash and URL-query implementations, while recommending createJSONStorage for a compliant adapter.
type StateStorage = {
getItem: (name: string) => string | null | Promise<string | null>
setItem: (name: string, value: string) => void | Promise<void>
removeItem: (name: string) => void | Promise<void>
}| Name | Type | Description |
|---|---|---|
storage | () => StateStorage | A storage factory supplied to persist; it returns the adapter used for persistence. |
A storage-adapter type used by persist; the page describes it as the return type of the storage option.
zustand/middleware when annotating a custom storage adapter.import { createJSONStorage, persist, StateStorage } from 'zustand/middleware'
const hashStorage: StateStorage = {
getItem: (key) => new URLSearchParams(location.hash.slice(1)).get(key),
setItem: (key, value) => {
const params = new URLSearchParams(location.hash.slice(1))
params.set(key, value)
location.hash = params.toString()
},
removeItem: (key) => {
const params = new URLSearchParams(location.hash.slice(1))
params.delete(key)
location.hash = params.toString()
},
}
const storage = createJSONStorage(() => hashStorage)
void persist(() => ({ count: 0 }), { name: 'counter', storage })Implements a hash-backed storage adapter and converts it into persist-compatible JSON storage.
Persist state in a URL hash or query string.
Use browser or mobile storage with persist.
Choose between URL parameters and localStorage.
StateStorage is the adapter shape consumed by persist for storing serialized state. It lets the middleware use a custom backend instead of its default localStorage-based storage.
Follow-up: How would you adapt an asynchronous backend? Use an async-compatible storage implementation and account for the cost of asynchronous persistence during rehydration and writes.
Import StateStorage from zustand/middleware and implement the storage methods against the chosen backend. The documentation shows this pattern for URL hashes and query parameters.
Follow-up: How can JSON serialization be added without duplicating parsing logic? Pass the adapter through createJSONStorage and provide that result to persist.
The persist option named storage is a function returning StateStorage, and its documented default is createJSONStorage(() => localStorage). A custom adapter replaces that default.
Follow-up: Why is the option a function rather than a storage object? A factory permits deferred access to browser-only storage and supports constructing the backend when needed.
persistcreateJSONStoragelocalStorageAsyncStorage