Session-scoped persistence
Persisting a store in browser session storage instead of the default local storage.
Zustand · Function
Creates a Zustand persistence storage adapter around a custom storage engine. It serializes and parses persisted values as JSON, with optional replacer and reviver customization.
createJSONStorage wraps a storage provider returned by a getter and adapts it to Zustand's persisted-state storage interface using JSON serialization. Optional replacer and reviver callbacks customize values during serialization and parsing.
(getStorage: () => StateStorage, options?: JsonStorageOptions) => StateStorage| Name | Type | Description |
|---|---|---|
getStorage | () => StateStorage | Function returning the underlying storage implementation to adapt. |
options | JsonStorageOptions | Optional JSON serialization and parsing configuration, including replacer and reviver callbacks. |
PersistStorage
toJSON() conversion, because a Date reaches the callback as a string.zustand/middleware.import { createJSONStorage } from 'zustand/middleware'
const storage = createJSONStorage(() => sessionStorage, {
reviver: (key, value) => {
if (value && value.type === 'date') return new Date(value.value)
return value
},
replacer: (key, value) => {
if (key === 'someDate') return { type: 'date', value }
return value
},
})
console.log(storage)Creates a JSON-compatible storage adapter around sessionStorage and customizes Date serialization and deserialization.
Persisting a store in browser session storage instead of the default local storage.
Connecting Zustand persistence to a custom storage engine that follows StateStorage.
Preserving or reconstructing special values such as tagged Dates during JSON conversion.
It accepts a function returning a StateStorage and optionally JsonStorageOptions, then returns a PersistStorage adapter. The adapter uses JSON parsing and stringification to make the underlying storage suitable for Zustand persistence.
Follow-up: Why is the storage argument a getter instead of a storage object? The getter is evaluated lazily, so importing a store does not immediately access unavailable browser APIs during SSR.
The first argument is getStorage, a zero-argument function that returns the underlying StateStorage. The optional second argument provides JSON serialization settings such as replacer and reviver callbacks.
Follow-up: How could custom Date handling be implemented? Return a tagged object from replacer and reconstruct a Date when reviver sees that tag.
It does not perform runtime validation of parsed data. Values read from storage are cast to the state type, so applications needing protection against malformed persisted data should provide a validating custom PersistStorage.
Follow-up: What risk remains even with TypeScript state types? TypeScript types do not validate runtime storage contents, so stale or tampered serialized data can still enter the application.
persistStateStoragePersistStorageJsonStorageOptionssessionStoragelocalStorage