Wocha Docs

Protect

Conditional rendering based on authentication, roles, and permissions.

The <Protect> component gates content behind authentication, role checks, or SpiceDB permission checks. Combine role and permission — both must pass when both are set.

Installation

pnpm add @wocha/ui @wocha/react
Or scaffold with the CLI
npx @wocha/cli init --framework nextjs
import { Protect } from "@wocha/ui";

Basic usage

<Protect fallback={<p>Please sign in.</p>}>
  <Dashboard />
</Protect>

Props

PropTypeDefaultDescription
permissionPermissionCheckPermission check — requires authenticated user with allowed permission
rolestringRole name — user must have matching role claim
fallbackReactNodeRendered when unauthenticated or unauthorised
childrenReactNodeContent rendered when authorised

PermissionCheck

{
  resource: { type: string; id: string };
  permission: string;
  subject?: { type: string; id: string };
}

Examples

// Auth gate only
<Protect fallback={<SignIn />}>
  <Dashboard />
</Protect>
 
// Role gate
<Protect role="admin" fallback={<p>Admins only.</p>}>
  <AdminSettings />
</Protect>
 
// Permission gate
<Protect
  permission={{
    resource: { type: "document", id: "doc_123" },
    permission: "edit",
  }}
  fallback={<p>You cannot edit this document.</p>}
>
  <EditForm />
</Protect>

useProtectState hook

For imperative checks in custom components:

import { useProtectState } from "@wocha/ui";
 
const { allowed, isLoading } = useProtectState({
  role: "admin",
  permission: { resource: { type: "org", id: orgId }, permission: "manage" },
});

Framework notes

Permission checks require apiUrl on your provider. Works in React and Next.js client components.

  • Show — declarative when prop alternative
  • @wocha/testing — mock provider for component tests

On this page