Use typed browser storage helpers
Read, write, remove, validate, and test JSON-serialized browser values outside component render lifecycles.
Storage is persisted client state. For in-memory coordination across Preact island roots on one page, use stores instead.
Use raw helpers outside components
import { getLocalStorageItem, removeLocalStorageItem, setLocalStorageItem } from "brix/storage";
import { profileKey } from "./storage-keys.ts";
setLocalStorageItem(profileKey, { displayName: "Ada", visits: 3 });
const profile = getLocalStorageItem(profileKey);
removeLocalStorageItem(profileKey);
Session equivalents are getSessionStorageItem, setSessionStorageItem, and
removeSessionStorageItem. Generic getStorageItem, setStorageItem, and removeStorageItem take a
supplied Storage first, and therefore work with compatible in-memory or platform implementations.
All values are JSON encoded, including strings. Do not read the underlying item and assume its stored text equals the logical string value.
Validation and errors
Reads are lenient because browser data may be malformed or from an older schema:
- Valid JSON is parsed through Zod and returns schema output.
- Malformed JSON or schema-invalid data returns
null. - Zod transformations and ordinary object-key stripping apply to both reads and writes.
Raw writes are strict. They parse before writing and throw for schema-invalid input, which exposes a developer error. Hook writes are UI-safe: invalid input leaves both storage and rendered state unchanged. If serialization or persistence fails, a hook retains its previous value instead of claiming an unpersisted update succeeded.
Do not use storage for secrets, authorization decisions, or trustworthy server state. Browser users can inspect and modify it. Validate again at every API or server boundary.
SSR and unavailable storage
The local and session convenience APIs do not access window during SSR:
- Reads return
null. - Writes and removals are no-ops.
- Hooks use lazy initialization and initially render with
nullon the server.
Browser privacy settings, sandboxing, and quota failures degrade similarly: reads return null, and
writes or removals do not break rendering. Account for server-to-client changes when persisted data
affects visible markup; keep the server fallback deterministic to avoid hydration surprises. See
islands for serialization and hydration boundaries.
Test behavior
Use browser component tests for hooks, events, and cross-tab behavior. For raw generic helpers, inject
a small test Storage implementation and test valid values, malformed JSON, schema migrations,
removal, and write failures. Reset keys between tests to prevent state leakage.
brix test --project browser
brix test --project node
brix check
See testing for selecting browser and node projects. Persisted values are independent of Brix's server-side data caching.