Wocha Docs

shadcn Components

Copy-to-install Wocha auth components for shadcn/ui projects.

@wocha/shadcn provides Wocha authentication components designed for shadcn/ui projects. Components are installed as source files into your codebase — you own the markup and can customise it with Tailwind.

For pre-built, themed components with a CSS variable system, see @wocha/ui. For headless hooks only, see @wocha/react.

How it differs from @wocha/ui

@wocha/shadcn@wocha/ui
DistributionCopy-paste via shadcn CLI or manual copynpm package with bundled CSS
Stylingshadcn primitives + your Tailwind theme.wocha- scoped CSS + WochaThemeProvider
CustomisationEdit copied source files directlyappearance props and theme variables
Composition APINot included (simpler surface)UserButton.Action, UserProfile.Page, etc.
Best forTeams already using shadcn/uiTeams wanting turnkey auth UI

Both packages use the same @wocha/react hooks under the hood.

Prerequisites

  1. shadcn/ui — run npx shadcn@latest init in your project
  2. @wocha/react — install and configure WochaProvider (or @wocha/nextjs for App Router)
  3. Base shadcn components — install primitives before Wocha components:
npx shadcn@latest add button card input label dropdown-menu tabs table

Set apiUrl in your provider config for profile management, organisation APIs, and permission checks.

Installation

shadcn CLI

Add the Wocha registry to components.json:

{
  "registries": {
    "@wocha": "https://raw.githubusercontent.com/wocha-dev/wocha/main/sdks/shadcn/registry/{name}.json"
  }
}

Install individual components:

npx shadcn@latest add @wocha/wocha-sign-in
npx shadcn@latest add @wocha/wocha-user-button
npx shadcn@latest add @wocha/wocha-org-switcher

The CLI installs shadcn registryDependencies (e.g. button, card) automatically and copies Wocha source to components/wocha/.

Manual copy

mkdir -p components/wocha
cp node_modules/@wocha/shadcn/components/*.tsx components/wocha/

Adjust @/components/ui/* imports if your path aliases differ.

Quick start

App.tsx
import { WochaProvider } from "@wocha/react";
import { WochaSignIn } from "@/components/wocha/sign-in";
import { WochaUserButton } from "@/components/wocha/user-button";
 
const config = {
  issuer: import.meta.env.VITE_WOCHA_ISSUER,
  clientId: import.meta.env.VITE_WOCHA_CLIENT_ID,
  redirectUri: window.location.origin + "/callback",
  apiUrl: import.meta.env.VITE_WOCHA_API_URL,
};
 
export function App() {
  return (
    <WochaProvider config={config}>
      <header className="flex items-center justify-end gap-4 p-4">
        <WochaUserButton />
      </header>
      <main className="mx-auto max-w-md p-4">
        <WochaSignIn />
      </main>
    </WochaProvider>
  );
}

Component reference

WochaSignIn / WochaSignInForm

Sign-in card with email/password fields and optional social provider buttons. Submits trigger the hosted Wocha OAuth flow.

import { WochaSignIn } from "@/components/wocha/sign-in";
 
<WochaSignIn showSocial />
PropTypeDefaultDescription
showSocialbooleantrueShow Google and GitHub buttons
onSuccess() => voidCalled after successful sign-in
classNamestringAdditional card classes

WochaSignInForm is an alias that re-exports WochaSignIn.

WochaSignUp / WochaSignUpForm

Sign-up card that starts the hosted registration flow.

import { WochaSignUp } from "@/components/wocha/sign-up";
 
<WochaSignUp />
PropTypeDefaultDescription
classNamestringAdditional card classes

WochaUserButton

Compact avatar dropdown with user info and sign-out.

import { WochaUserButton } from "@/components/wocha/user-button";
 
<WochaUserButton />
PropTypeDefaultDescription
classNamestringAdditional trigger classes

WochaUserMenu

Avatar dropdown with display name, profile link, optional settings link, and sign-out.

import { WochaUserMenu } from "@/components/wocha/user-menu";
 
<WochaUserMenu profileUrl="/account" settingsUrl="/settings" />
PropTypeDefaultDescription
profileUrlstring"/account"Link for profile menu item
settingsUrlstringOptional settings link
classNamestringAdditional trigger classes

WochaOrgSwitcher

Organisation selector dropdown. Hidden when the user belongs to a single organisation.

import { WochaOrgSwitcher } from "@/components/wocha/org-switcher";
 
<WochaOrgSwitcher getOrgLabel={(id) => orgNames[id] ?? id} />
PropTypeDefaultDescription
getOrgLabel(orgId: string) => stringMap org IDs to display names
classNamestringAdditional button classes

WochaAuthGuard

Route protection wrapper. Without permission, renders children only when authenticated. With permission, delegates to SpiceDB via Protect.

import { WochaAuthGuard } from "@/components/wocha/auth-guard";
 
<WochaAuthGuard fallback={<p>Please sign in.</p>}>
  <Dashboard />
</WochaAuthGuard>
PropTypeDefaultDescription
permissionPermissionCheckSpiceDB permission required
loadingFallbackReactNodeShown while session loads
fallbackReactNodeShown when unauthenticated or denied
childrenReactNodeProtected content

WochaMfaSetup

TOTP MFA enrollment wizard with backup codes. Uses the Account API via useMfa.

import { WochaMfaSetup } from "@/components/wocha/mfa-setup";
 
<WochaMfaSetup />
PropTypeDefaultDescription
classNamestringAdditional card classes

WochaUserProfile

Card-based profile management with Profile, Security, and Sessions tabs. Uses useProfile, useSessions, and useMfa from @wocha/react.

import { WochaUserProfile } from "@/components/wocha/user-profile";
 
<WochaUserProfile passwordSettingsUrl="/account/password" />
PropTypeDefaultDescription
passwordSettingsUrlstringHosted password change URL
fallbackReactNodeShown while loading
classNamestringAdditional card classes

Requires accountApiUrl or apiUrl in your provider config.

WochaOrgProfile

Organisation management card with Overview, Members, and Settings tabs.

import { WochaOrgProfile } from "@/components/wocha/org-profile";
 
<WochaOrgProfile orgId="org_abc123" />
PropTypeDefaultDescription
orgIdstringactive orgOrganisation to manage
apiUrlstringfrom configCustomer API base URL
fallbackReactNodeShown while loading
classNamestringAdditional card classes

WochaCreateOrg

Form to create a new organisation via the Customer API.

import { WochaCreateOrg } from "@/components/wocha/create-org";
 
<WochaCreateOrg
  onSuccess={(org) => console.log(org.id)}
  afterCreateUrl="/dashboard"
/>
PropTypeDefaultDescription
apiUrlstringfrom configCustomer API base URL
onSuccess(org) => voidCalled after creation
onError(error) => voidCalled on failure
afterCreateUrlstringRedirect after success
classNamestringAdditional card classes

WochaShow

Conditional render component matching @wocha/ui's Show. Supports signed-in/out states, role checks, permission checks, and custom predicate functions.

import { WochaShow } from "@/components/wocha/show";
 
<WochaShow when="signed-out" fallback={<SignInPrompt />}>
  <Dashboard />
</WochaShow>
 
<WochaShow when={{ role: "admin" }}>
  <AdminTools />
</WochaShow>
 
<WochaShow when={{ permission: "billing:manage" }}>
  <BillingPanel />
</WochaShow>
 
<WochaShow when={(has) => has({ role: "admin" }) || has({ permission: "editor" })}>
  <EditorToolbar />
</WochaShow>
PropTypeDefaultDescription
whenShowWhenCondition to evaluate
fallbackReactNodeShown when condition is false or loading
childrenReactNodeContent when condition is true

ShowWhen accepts "signed-in", "signed-out", { permission: string }, { role: string }, or a predicate function.

Customisation

After installation, components live in components/wocha/. Because you own the source:

  • Edit JSX and Tailwind classes directly
  • Swap shadcn primitives (e.g. replace Card with a custom wrapper)
  • Add or remove fields, sections, and menu items

Theme changes via shadcn's globals.css CSS variables (--primary, --radius, etc.) apply automatically to installed components.

Next.js guidance

shadcn components import only from @wocha/react — they do not require @wocha/ui. For Next.js App Router:

  1. Install @wocha/nextjs and configure the OAuth BFF handler
  2. Wrap your app with WochaSessionProvider from @wocha/nextjs/client
  3. Pass apiUrl to the session provider for Customer API and permission features
  4. Install shadcn Wocha components as usual — no additional bridge is needed

Server Components cannot use these components directly (they are "use client"). Import them in Client Components or pages that render client boundaries.

// app/sign-in/page.tsx
"use client";
 
import { WochaSignIn } from "@/components/wocha/sign-in";
 
export default function SignInPage() {
  return <WochaSignIn />;
}

Registry development

To rebuild the registry after changing component source:

cd sdks/shadcn && pnpm build

This runs shadcn build and outputs item JSON files to registry/.

Learn more