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.