Authentication

The boilerplate uses Better Auth for authentication, running inside the Convex backend.

Supported Methods

  • Email/Password — With email verification and password reset
  • Google OAuth — One-click Google sign-in
  • GitHub OAuth — Sign in with GitHub

How It Works

Authentication uses a cross-domain setup where:

  1. The auth client runs in the browser (src/shared/auth-client.ts)
  2. Auth endpoints are hosted on the Convex site domain (.convex.site)
  3. Sessions are stored in localStorage (not cookies)

This means auth is client-side only — the server cannot verify auth state during SSR.

Auth Guard

Protected pages use an auth guard state machine with these states:

StateMeaning
idleInitial state
checkingWaiting for auth to resolve
ott_exchangeOAuth callback in progress
authenticatedUser is logged in
unauthenticatedNo session found

The guard handles edge cases like OAuth One-Time Token exchanges and prevents infinite loading states with a 10-second timeout.

Team Context

After authentication, the team context loads automatically:

  • First team is selected by default
  • Selection persists in localStorage
  • Team switcher appears in the sidebar when user has multiple teams