Wocha Docs

UI Components

Themed, customisable React components for sign-in, user management, and enterprise setup.

@wocha/ui provides pre-built, themed React components for Wocha authentication. Use them alongside @wocha/react (SPAs) or @wocha/nextjs (App Router) for polished auth UI without building forms from scratch.

For unstyled, headless primitives, see @wocha/react — UI components wrap the same auth context with CSS custom properties and accessible markup.

Installation

pnpm add @wocha/ui @wocha/react
Or scaffold with the CLI
npx @wocha/cli init --framework nextjs

For Next.js apps, install @wocha/nextjs instead of @wocha/react:

pnpm add @wocha/ui @wocha/nextjs
Or scaffold with the CLI
npx @wocha/cli init --framework nextjs

Import the stylesheet once in your root layout or entry file:

import "@wocha/ui/styles.css";

Peer dependencies: React 18+, and one of @wocha/react or @wocha/nextjs.

Quick start

App.tsx
import { WochaProvider } from "@wocha/react";
import { WochaThemeProvider, SignIn, UserButton } from "@wocha/ui";
import "@wocha/ui/styles.css";
 
const config = {
  issuer: import.meta.env.VITE_WOCHA_ISSUER,
  clientId: import.meta.env.VITE_WOCHA_CLIENT_ID,
  redirectUri: window.location.origin + "/callback",
};
 
export function App() {
  return (
    <WochaProvider config={config}>
      <WochaThemeProvider>
        <header>
          <UserButton profileUrl="/account" />
        </header>
        <SignIn redirectUrl="/dashboard" />
      </WochaThemeProvider>
    </WochaProvider>
  );
}

Components

<SignIn> and <SignUp>

Styled auth forms that redirect to Wocha hosted login or registration.

import { SignIn, SignUp } from "@wocha/ui";
 
<SignIn
  redirectUrl="/dashboard"
  organisation="org_abc123"
  providers={["google", "github"]}
  passkeys
  appearance={{
    variables: { "--wocha-color-primary": "#6366f1" },
  }}
/>
 
<SignUp
  redirectUrl="/welcome"
  title="Join Acme Corp"
  description="Create an account to get started."
/>
PropDescription
redirectUrlURL to return to after auth
organisationOrganisation ID hint for hosted login
providersSocial buttons to show (google, github, apple, microsoft)
passkeysShow passkey sign-in button
appearancePer-component theme overrides
withCardWrap in AuthCard (default: true)

<UserButton>

Dropdown with avatar, name, email, and menu actions (Profile, Organisation, Sign out).

import { UserButton } from "@wocha/ui";
 
<UserButton
  variant="full"
  profileUrl="/account"
  organisationUrl="/settings/org"
/>

Use variant="compact" for avatar-only display.

<OrgSwitcher>

Organisation switcher for multi-org users.

import { OrgSwitcher } from "@wocha/ui";
 
<OrgSwitcher
  getOrgLabel={(id) => orgNames[id] ?? id}
  createOrganisationUrl="/organisations/new"
  showSingle
/>

<Protect>

Conditional rendering based on authentication, roles, or SpiceDB permissions.

import { Protect } from "@wocha/ui";
 
// Auth gate
<Protect fallback={<p>Please sign in.</p>}>
  <Dashboard />
</Protect>
 
// Permission gate
<Protect
  permission={{
    resource: { type: "document", id: "doc_123" },
    permission: "edit",
  }}
  fallback={<p>You cannot edit this document.</p>}
>
  <EditForm />
</Protect>

Combine role and permission — both must pass when both are set.

Passkey components

<PasskeyButton> handles WebAuthn registration and authentication. Enable passkeys on <SignIn passkeys /> or use the button standalone:

import { PasskeyButton } from "@wocha/ui";
 
// Sign in with passkey
<PasskeyButton mode="authenticate" onSuccess={() => router.push("/dashboard")} />
 
// Register a new passkey (e.g. in account settings)
<PasskeyButton mode="register" displayName="Alice's MacBook" />

Requires passkey endpoints configured in your auth handler (see Passkeys guide).

<UserProfile> and <UserPortal>

Full-page account management with profile editing, password settings, MFA (TOTP and backup codes), passkey management, session revocation, connected social accounts, and organisation membership. Requires apiUrl on your provider.

// app/account/page.tsx
import { UserPortal, UserProfile } from "@wocha/ui";
 
export default function AccountPage() {
  return (
    <UserPortal
      title="My account"
      sections={["profile", "security", "sessions", "connections", "organisations"]}
      passwordSettingsUrl="/account/password"
    />
  );
}
 
// Or embed sections directly
<UserProfile sections={["profile", "security"]} />

<OrganizationProfile>

Organisation management with overview, members, settings, and enterprise SSO status. Uses the Customer API with the signed-in user's access token.

import { OrganizationProfile } from "@wocha/ui";
 
<OrganizationProfile orgId="org_abc123" />

Tabs: Overview, Members (invite, role management, remove with confirmation), Settings, Security (SSO connection status).

Interactive tools

<AuthCard>

Styled card wrapper used internally by <SignIn> and <SignUp>. Available for custom auth UI:

import { AuthCard, WochaLogo } from "@wocha/ui";
 
<AuthCard
  logo={<WochaLogo />}
  title="Reset password"
  description="Enter your email to receive a reset link."
  footer={<a href="/sign-in">Back to sign in</a>}
>
  {/* custom form */}
</AuthCard>

Headless vs styled modes

LayerPackageUse when
Headless@wocha/reactYou want full control over markup and styling
Styled@wocha/uiYou want production-ready components with theming

Headless components from @wocha/react (SignIn, SignOut, Protect, Authenticated) expose behaviour without CSS. UI components add .wocha- scoped styles, keyboard navigation, ARIA semantics, and theme variables on top of the same auth context.

You can mix both — use UI components for auth pages and headless hooks elsewhere:

import { useSession } from "@wocha/react";
import { SignIn, UserButton } from "@wocha/ui";

Theming and customisation

All styles use CSS custom properties with the .wocha- prefix to avoid conflicts with your app.

Theme provider

<WochaThemeProvider
  appearance={{
    theme: "dark",       // "light" | "dark" | "system"
    radius: "lg",
    variables: {
      "--wocha-color-primary": "#818cf8",
      "--wocha-color-background": "#0f0f0f",
      "--wocha-font-family": "'Inter', sans-serif",
    },
  }}
>
  {children}
</WochaThemeProvider>

Per-component overrides via the appearance prop on individual components.

Theme editor

Use the interactive Theme Editor to preview colours, radius, and typography, then copy the generated WochaThemeProvider configuration into your app.

Raw CSS

@import "@wocha/ui/styles.css";
 
.wocha-root[data-theme="light"] {
  --wocha-color-primary: #7c3aed;
}

Framework integration

UI components work with any React setup that provides Wocha auth context:

FrameworkProviderTheme provider
React SPAWochaProvider from @wocha/reactWochaThemeProvider
Next.js App RouterWochaSessionProvider from @wocha/nextjs/clientWochaThemeProvider sdk="nextjs"

Set apiUrl on both the session provider and theme provider when using permission checks or profile management features.

Enterprise widgets

Embeddable components for customer self-service — SSO, SCIM, and domain verification. Each widget accepts a portal token from the Wocha Console.

import {
  EnterpriseSetup,
  SSOSetup,
  SCIMSetup,
  DomainVerification,
} from "@wocha/ui/enterprise";
 
<EnterpriseSetup
  portalToken={portalToken}
  portalBaseUrl="https://console.wocha.ai"
  onComplete={() => console.log("Setup complete")}
/>

Tree-shakeable imports

Import components individually to reduce bundle size:

import { SignIn } from "@wocha/ui/sign-in";
import { UserButton } from "@wocha/ui/user-button";
import { Protect } from "@wocha/ui/protect";

Learn more