Skip to content
v3.0.1 — MCP OAuth, organizations, passkeys, SSR adaptersChangelog
Convex Auth
Esc
↑↓navigate↵open⌘Jpreview
On this page

React

React hooks and the client for convex-auth.

@vortex-api/convex-auth/react exposes a provider and hooks that wrap the Convex actions configured in convex/auth.ts. This is the client-side contract for every React app — Vite SPAs build on it directly, and the TanStack Router, Next.js, TanStack Start, and React Native guides layer on top of it.

Install

pnpm add @vortex-api/convex-auth convex
echo 'VITE_CONVEX_URL=https://<your-deployment>.convex.cloud' >> .env.local

The Convex backend wiring (component mount, convex/auth.ts, convex/http.ts) is covered in Installation.

Provider

ConvexAuthClientProvider replaces the plain ConvexProvider and wires the auth action references from api.auth:

// src/main.tsx
import { ConvexReactClient, ConvexProvider } from "convex/react";
import { ConvexAuthClientProvider } from "@vortex-api/convex-auth/react";
import { api } from "../convex/_generated/api";
import App from "./App";

const convex = new ConvexReactClient(import.meta.env.VITE_CONVEX_URL);

function Root() {
  return (
    <ConvexProvider client={convex}>
      <ConvexAuthClientProvider actions={api.auth}>
        <App />
      </ConvexAuthClientProvider>
    </ConvexProvider>
  );
}

actions must be the api.auth object that re-exports the functions returned by convexAuth.

useAuthActions

useAuthActions is the low-level hook for signing in, signing up, signing out, and managing 2FA.

import { useAuthActions } from "@vortex-api/convex-auth/react";

export function SignIn() {
  const { signIn, isLoading, isAuthenticated } = useAuthActions();

  async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
    event.preventDefault();
    const formData = new FormData(event.currentTarget);
    await signIn({
      email: formData.get("email") as string,
      password: formData.get("password") as string,
    });
  }

  // ...
}

Returns

Property Type Description
isLoading boolean Whether an auth action is in flight.
isAuthenticated boolean Whether the current session is authenticated.
user object | null Current user object.
token string | null Current session JWT.
sessionId string | null Current session id.
signUp async (args) => Session Email/password sign-up.
signIn async (args) => Session Email/password sign-in.
signInWithMagicLink async (args) => Result Sign in via a magic link.
signInWithRedirect async (args) => Result Start an OAuth redirect flow.
oauthCallback async (args) => Result Complete the OAuth callback.
signOut async () => void Invalidate the session.
sendEmailVerification async (args) => Result Send an email-verification email.
verifyEmail async (token) => Result Verify an email from a link.
sendPasswordReset async (args) => Result Send a password-reset email.
resetPassword async (args) => Result Reset the password with a token.
changeEmail async (args) => Result Request an email change.
twoFactor.* object TOTP enable, verify, disable, and backup-code helpers.

signIn and signUp accept { email, password, rememberMe?, callbackURL?, name? }.

signInWithRedirect accepts { provider: "google" | "github" | "discord", callbackURL?, errorURL?, newUserURL? }.

useConvexAuthClient

useConvexAuthClient wraps useAuthActions in a drop-in client shape. Use this if you are porting an existing auth client.

import { useConvexAuthClient } from "@vortex-api/convex-auth/react";

export function SignInPage() {
  const client = useConvexAuthClient();

  async function handleSubmit(email: string, password: string) {
    const { data, error } = await client.signIn.email({ email, password });
    if (error) {
      console.error(error.message);
    }
  }

  const session = client.useSession();
  // session.data.user, session.data.session, session.isPending

  return <button onClick={() => client.signOut()}>Sign out</button>;
}

Client methods

Method Description
useSession React hook returning { data: { user, session }, isPending }.
signIn.email Email/password sign-in.
signIn.social OAuth sign-in with redirect.
signUp.email Email/password sign-up.
signOut Sign the user out.
forgetPassword Send a password-reset email.
resetPassword Reset the password with a token.
sendVerificationEmail Send an email-verification email.
verifyEmail Verify an email from a token.
changeEmail Request an email change.
twoFactor.enable Start TOTP enrollment. Returns totpURI and backupCodes.
twoFactor.verifyTotp Confirm a TOTP code.
twoFactor.verifyBackupCode Confirm a backup code.
twoFactor.disable Disable 2FA.
twoFactor.generateBackupCodes Regenerate backup codes.

Other hooks

@vortex-api/convex-auth/react also ships form and UI components. The most commonly used ones:

  • useConvexAuthUser(authClient) — returns { user, isLoaded, isSignedIn } in a Clerk-compatible shape.
  • useConvexAuthSessionList(authClient) — list and refetch active sessions.
  • useConvexAuthRevokeSession(authClient) — revoke a session or all other sessions.
  • useConvexAuthForgotPassword(authClient) — request a password reset.
  • useConvexAuthResetPassword(authClient) — complete a password reset.
  • useConvexAuthVerifyEmail(authClient) — verify an email from a token.
  • useConvexAuthEnableTwoFactor(authClient) — start TOTP enrollment.
  • useConvexAuthVerifyTotp(authClient) — confirm a TOTP code.

Most of these take the auth client returned by useConvexAuthClient().

Example apps

Three runnable React examples live under examples/. Copy each .env.example to .env.local and point it at a Convex deployment — give each example its own deployment, since pointed at one they overwrite each other’s functions. For OAuth, also set the provider credentials on the deployment:

cp examples/oauth/.env.example examples/oauth/.env.local
pnpm dlx convex env set GITHUB_CLIENT_ID '...'
  • examples/react — Vite + React sign-up/sign-in form on ConvexAuthClientProvider + useAuthActions.

    cd examples/react
    pnpm install
    pnpm run dev
  • examples/tanstack-router — Vite + React with @tanstack/react-router. See the dedicated TanStack Router guide for the route-guard pattern it implements.

  • examples/oauth — Google, GitHub, and Discord buttons on the same client.

Anonymous local backends bind 127.0.0.1:3210/3211; to run several at once give each .env.local its own port pair (e.g. 3214/3215) before the first convex dev — the backend binds the ports in CONVEX_URL/CONVEX_SITE_URL.

All examples use a committed _generated directory. If you point an example at your own deployment, regenerate bindings:

CONVEX_DEPLOYMENT=dev:<your-deployment> pnpm dlx convex codegen --typecheck=disable

Next steps

Was this page helpful?