advanced
Persist middleware
Persist selected client state with migrations, hydration handling, and storage-safety decisions.
The `persist` middleware writes part of the store to storage (localStorage, sessionStorage, async adapters) and rehydrates on load. Configure `name`, `partialize` to whitelist fields, and `version` + `migrate` for schema changes.
import { create } from 'zustand';
import { persist } from 'zustand/middleware';
const useSettings = create(
persist(
(set) => ({
theme: 'light',
setTheme: (theme) => set({ theme }),
}),
{
name: 'settings',
partialize: (s) => ({ theme: s.theme }),
version: 1,
},
),
);
Handle hydration mismatches in SSR: delay render or use `onRehydrateStorage`. Never persist tokens or PII without encryption and threat modeling.
The trade-off is restored UX across sessions versus storage limits, migrations, and leaking sensitive fields.
On interviews: what to persist, migration strategy, and hydration flash.
Common pitfalls: persisting entire store including actions, no version bump on shape change, and stale persisted state overriding server truth.
Checklist:
- partialize sensitive/safe fields only.
- versioned migrations.
- Plan SSR rehydration UX.
- Server state still refetched after hydrate.