Wocha Docs

React quickstart

Add Wocha authentication to a React SPA with PKCE.

Add Wocha sign-in to a React single-page application using @wocha/react. The SDK implements the OAuth 2.0 authorisation code flow with PKCE as a public client — no client secret required.

Prerequisites

  • Node.js 18+
  • React 18+ (Vite recommended)
  • A Wocha project with a public OAuth application
  • Redirect URI registered: http://localhost:5173/callback

What you'll build

A React SPA with PKCE sign-in, callback handling, and session hooks for your components.

your-app.local

Welcome back

After sign-in

✓ Session stored securely

✓ User profile available in your app

✓ Organisation context ready for multi-tenant features

Installation

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

Environment variables

.env
VITE_WOCHA_ISSUER=https://your-tenant.auth.wocha.ai
VITE_WOCHA_CLIENT_ID=your-client-id
VITE_WOCHA_API_URL=https://your-tenant.api.wocha.ai  # optional

Provider setup

Wrap your app in WochaProvider:

src/main.tsx
import { WochaProvider } from "@wocha/react";
 
<WochaProvider config={{
  issuer: import.meta.env.VITE_WOCHA_ISSUER,
  clientId: import.meta.env.VITE_WOCHA_CLIENT_ID,
  redirectUri: window.location.origin + "/callback",
}}>
  {children}
</WochaProvider>

Callback route

Handle the OAuth redirect on /callback:

src/pages/Callback.tsx
import { useEffect } from "react";
import { useNavigate } from "react-router-dom";
import { useSession } from "@wocha/react";
 
export function Callback() {
  const navigate = useNavigate();
  const { status } = useSession();
 
  useEffect(() => {
    if (status === "authenticated") navigate("/dashboard");
  }, [status, navigate]);
 
  return <p>Completing sign-in…</p>;
}

Sign in

Use the session hook to trigger login:

import { useSession } from "@wocha/react";
 
export function SignInButton() {
  const { status, login, logout } = useSession();
 
  if (status === "loading") return <button disabled>Loading…</button>;
  if (status === "authenticated") {
    return <button onClick={() => logout()}>Sign out</button>;
  }
  return <button onClick={() => login()}>Sign in</button>;
}

Next steps

On this page