UNPKG

permix

Version:

Permix is a lightweight, framework-agnostic, type-safe permissions management library for JavaScript applications on the client and server sides.

101 lines (73 loc) 2.98 kB
--- name: permix-ssr description: >- Serializes Permix permissions for SSR: dehydrate, hydrate, client setup, PermixHydrate, Next.js and TanStack Start. Use when passing permissions from server to client or permix.dehydrate in SSR apps. type: sub-skill library: permix library_version: '4.1.1' requires: - permix-getting-started - permix-frontend sources: - 'letstri/permix:docs/content/docs/guide/hydration.mdx' - 'letstri/permix:docs/content/docs/integrations/next.mdx' - 'letstri/permix:docs/content/docs/integrations/tanstack-start.mdx' - 'letstri/permix:permix/src/next/index.ts' - 'letstri/permix:permix/src/tanstack-start/index.ts' --- # Permix — SSR and hydration Docs: https://permix.letstri.dev/docs/guide/hydration ## Why dehydrate? Send a JSON snapshot of booleans to the browser so the first paint can respect permissions without re-fetching policy on the client. ## Server ```ts permix.setup(serverRules) const state = permix.dehydrate() // { post: { create: true, read: false } } — functions evaluated once without data ``` Pass `state` to the client (embed in HTML, RSC payload, loader data, etc.). ## Client ```ts permix.hydrate(state) // isReady() is still FALSE — hydrate only restores booleans ``` Function-based rules are **lost** in JSON (dehydration calls functions with no data; missing required data → `false`). **Always call `setup` again on the client** with full rules (including closures): ```ts permix.hydrate(serverState) permix.setup(clientRulesForUser) // restores functions + sets ready ``` Skipping client `setup` after hydrate leaves dynamic/ReBAC checks wrong. ## React ```tsx import { DehydratedState, PermixHydrate, PermixProvider } from 'permix/react' function App({ dehydratedState }: { dehydratedState: DehydratedState<typeof schema> }) { return ( <PermixProvider permix={permix}> <PermixHydrate state={dehydratedState}> <YourApp /> </PermixHydrate> </PermixProvider> ) } ``` Run client `permix.setup(...)` where you restore the session (e.g. after `PermixHydrate` mounts or in the same auth effect). ## Next.js / TanStack Start Use framework helpers from `permix/next` or `permix/tanstack-start` when available — they wire dehydrate/hydrate into the framework data flow. Docs: - https://permix.letstri.dev/docs/integrations/next - https://permix.letstri.dev/docs/integrations/tanstack-start ## Flow diagram ```text Server: setup(rules) → dehydrate() → send state Client: hydrate(state) → setup(fullRules) → isReady() → check() / usePermix ``` ## Pitfalls | Issue | Cause | |-------|--------| | UI stuck not ready | `hydrate` without follow-up `setup` | | Wrong dynamic checks | Relying on dehydrated booleans only | | Mismatch server/client | Different schemas or missing actions in client `setup` | For static-only permissions (all booleans), dehydrate + hydrate + `setup` with the same booleans is enough; still call `setup` to mark ready.