Your first sign-in flow
This guide assumes you’ve finished the self-host quickstart and have the operator dashboard open at http://localhost:8080/dashboard.
1. Create a project
Section titled “1. Create a project”From /dashboard/create-project, give the project a name + slug. The Dashboard provisions a production environment with a publishable key (pk_live_…) and a routing label like wise-otter-x4f. The publishable key encodes the Frontend API URL, so the SDK doesn’t need a separate config call to discover it.
Copy the pk_live_… from API keys in the sidebar — you’ll paste it into your app in step 3.
2. Spin up a React app
Section titled “2. Spin up a React app”npm create vite@latest my-app -- --template react-tscd my-appnpm installnpm install @authn-sh/sdk-react3. Wrap your app in <AuthnProvider>
Section titled “3. Wrap your app in <AuthnProvider>”import { StrictMode } from 'react'import { createRoot } from 'react-dom/client'import { AuthnProvider, SignedIn, SignedOut, SignIn, UserButton } from '@authn-sh/sdk-react'import '@authn-sh/ui/styles.css'
const PUBLISHABLE_KEY = import.meta.env.VITE_AUTHN_PUBLISHABLE_KEY
createRoot(document.getElementById('root')!).render( <StrictMode> <AuthnProvider publishableKey={PUBLISHABLE_KEY}> <SignedIn> <UserButton /> <p>You're signed in!</p> </SignedIn> <SignedOut> <SignIn routing="virtual" /> </SignedOut> </AuthnProvider> </StrictMode>,)Set the publishable key in a .env:
VITE_AUTHN_PUBLISHABLE_KEY=pk_live_…paste-yours-here4. Sign someone up
Section titled “4. Sign someone up”npm run dev, open the Vite URL, and you’ll see the <SignIn /> form. Click “Sign up” to register a new user. The verification email lands in Mailpit — copy the 6-digit code, paste it back into the form, and you’re signed in.
What just happened
Section titled “What just happened”- The SDK decoded
pk_live_…to find your FAPI URL and calledGET /v1/environment+GET /v1/clientto bootstrap. - Sign-up POSTed to
/v1/client/sign-ups, thenPOST .../challenges { strategy: "email_code" }sent the verification email. - After
POST .../challenges/{cid}/answer { code: "…" }, the server set a__sessionHttpOnly cookie.<SignedIn>started rendering its children;<UserButton>mounted with the user’s avatar.
Next stops:
- API keys — when to use
pk_vssk_. - Sessions and tokens — how the
__sessionJWT works. - Verify JWTs in a backend — read the operator’s session from a Laravel / Express / FastAPI request.