Authentication
Drop-in Supabase auth flows via the registry, plus the server-side confirm handler
Zeno ships the standard Supabase auth flows: magic-link and password sign-in, sign-up, email
verification, password recovery and reset, and sign-out. The UI flows are shadcn-style
components you install from the registry and own; the server-side OTP confirm handler is
headless and ships on npm as @zeno-lib/authentication.
Install
Add the flows you need from the registry. Each one installs into @/components/auth/* and brings
in the shadcn primitives it uses:
pnpm dlx shadcn@latest add zeno-lib/zeno/sign-in zeno-lib/zeno/auth-layoutOther flows: sign-up, email-sent, verify, error, recover-password, reset-password,
sign-out. Then install the server handler and the Supabase client:
pnpm add @zeno-lib/authentication @zeno-lib/supabaseWire the provider
Mount AuthProvider once, in the auth route group's layout, and pass it a Supabase client. It
provides the form state and the per-flow submit handlers through React context:
"use client"
import { AuthProvider } from "@/components/auth/components/context"
import { createClient } from "@zeno-lib/supabase/next-client"
export default function AuthLayout({ children }: { children: React.ReactNode }) {
return <AuthProvider supabase={createClient()}>{children}</AuthProvider>
}Render each flow on its route:
import { SignIn } from "@/components/auth/sign-in"
export default function Page() {
return <SignIn />
}The flows report errors with toast from
sonner, so mount <Toaster /> (add it with
pnpm dlx shadcn@latest add sonner) in your root layout.
The confirm route (server)
The confirm handler verifies magic links and OTPs on the server, never in a client component.
Mount it from the npm package at /confirm:
export { getRoute as GET } from "@zeno-lib/authentication/confirm/index"Route contract
The flows navigate to hard-coded paths, so mount these routes (or wire your own equivalents):
- After sending a magic link, the sign-in flow pushes to
/email-sent. - The verify screen's button opens
/confirm?token_hash=…&type=…. - The middleware (
@zeno-lib/supabase/next-middleware) redirects unauthenticated users to/sign-in.
Don't auto-redirect from the verify screen. The manual button click is a security measure. Email link scanners (such as Microsoft Safe Links) prefetch URLs and would consume a one-time OTP before the user clicks. Verification must stay behind the click.