Framework guides
Next.js
Add bao authentication to a Next.js app — client setup, protected routes, and server-side session access.
Install
npm install better-authCreate the auth client
Export a single instance from a shared module. Use NEXT_PUBLIC_AUTH_URL so the client works in both browser and server components.
// lib/auth-client.ts
import { createAuthClient } from "better-auth/client";
export const authClient = createAuthClient({
baseURL: process.env.NEXT_PUBLIC_AUTH_URL!,
});Add to .env.local:
NEXT_PUBLIC_AUTH_URL=https://my-app-production.workers.devSign in
// app/login/page.tsx
"use client";
import { authClient } from "@/lib/auth-client";
export default function LoginPage() {
async function handleLogin(formData: FormData) {
const { error } = await authClient.signIn.email({
email: formData.get("email") as string,
password: formData.get("password") as string,
});
if (!error) window.location.href = "/dashboard";
}
return (
<form action={handleLogin}>
<input name="email" type="email" />
<input name="password" type="password" />
<button type="submit">Sign in</button>
</form>
);
}Get the session in a Server Component
// app/dashboard/page.tsx
import { headers } from "next/headers";
import { redirect } from "next/navigation";
export default async function DashboardPage() {
const res = await fetch(
`${process.env.NEXT_PUBLIC_AUTH_URL}/api/auth/get-session`,
{ headers: await headers() }
);
const session = await res.json();
if (!session?.user) redirect("/login");
return <p>Hello {session.user.email}</p>;
}Protect routes with middleware
// middleware.ts
import { NextResponse, type NextRequest } from "next/server";
const PROTECTED = ["/dashboard"];
export async function middleware(request: NextRequest) {
const isProtected = PROTECTED.some((path) =>
request.nextUrl.pathname.startsWith(path),
);
if (!isProtected) return NextResponse.next();
const res = await fetch(
`${process.env.NEXT_PUBLIC_AUTH_URL}/api/auth/get-session`,
{ headers: request.headers },
);
const session = await res.json();
if (!session?.user) {
return NextResponse.redirect(new URL("/login", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard/:path*"],
};CORS
Add your Next.js origin to bao.config.json — see CORS configuration.