How can I implement better auth on a Next.js app router project?
This post might have stale content, as canary is 274 commits ahead.
how can i implement better auth on a next js app router project?
Perfect! Now I have comprehensive information. Let me provide you with a detailed guide:
##How to Implement Better Auth in a Next.js App Router Project
Here's a step-by-step guide based on the Better Auth source code:
###1. Install Better Auth
npm install better-auth
# or
pnpm add better-auth
###2. Set Up Environment Variables
Create a .env file in your project root:
# Generate a secret with: openssl rand -base64 32
BETTER_AUTH_SECRET=<your-generated-secret>
BETTER_AUTH_URL=http://localhost:3000
###3. Create Your Auth Instance
Create lib/auth.ts in your project:
import { betterAuth } from "better-auth";
import { nextCookies } from "better-auth/next-js";
export const auth = betterAuth({
secret: process.env.BETTER_AUTH_SECRET,
baseURL: process.env.BETTER_AUTH_URL,
database: {
// Configure your database (SQLite, PostgreSQL, MySQL, etc.)
// Example with better-sqlite3:
// database: new Database("./sqlite.db"),
},
emailAndPassword: {
enabled: true,
},
socialProviders: {
github: {
clientId: process.env.GITHUB_CLIENT_ID || "",
clientSecret: process.env.GITHUB_CLIENT_SECRET || "",
},
// Add other providers as needed
},
plugins: [
nextCookies(), // Handle cookies in server actions
],
});
###4. Create the API Route Handler
Create app/api/auth/[...all]/route.ts:
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";
export const { GET, POST } = toNextJsHandler(auth);
This single file handles all auth endpoints (/api/auth/sign-in, /api/auth/sign-up, etc.).
###5. Create the Auth Client
Create lib/auth-client.ts:
import { createAuthClient } from "better-auth/react";
export const authClient = createAuthClient({
// You can add client-side plugins here
});
###6. Set Up Route Protection (Optional)
Create proxy.ts for protecting routes:
import { getSessionCookie } from "better-auth/cookies";
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
export async function proxy(request: NextRequest) {
const sessionCookie = getSessionCookie(request);
if (!sessionCookie) {
return NextResponse.redirect(new URL("/sign-in", request.url));
}
return NextResponse.next();
}
export const config = {
matcher: ["/dashboard"], // Protect these routes
};
###7. Get Session in Server Components
import { auth } from "@/lib/auth";
import { headers } from "next/headers";
export async function DashboardPage() {
const session = await auth.api.getSession({
headers: await headers(),
});
if (!session) {
return <div>Not authenticated</div>;
}
return <div>Welcome {session.user.name}</div>;
}
###8. Use Auth Client in Client Components
"use client";
import { authClient } from "@/lib/auth-client";
import { useEffect, useState } from "react";
export function SignInForm() {
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const handleSignIn = async () => {
const { data, error } = await authClient.signIn.email({
email,
password,
callbackURL: "/dashboard",
}, {
onSuccess: () => {
// Handle success
},
onError: (ctx) => {
alert(ctx.error.message);
},
});
};
return (
<form onSubmit={(e) => { e.preventDefault(); handleSignIn(); }}>
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="Email"
/>
<input
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
placeholder="Password"
/>
<button type="submit">Sign In</button>
</form>
);
}
###9. Get Session in Server Actions
"use server";
import { auth } from "@/lib/auth";
import { headers } from "next/headers";
export async function getSessionAction() {
const session = await auth.api.getSession({
headers: await headers(),
});
return session;
}
###Key Points:
toNextJsHandler: Automatically handles the App Router request/response formatnextCookies()plugin: Ensures cookies are properly set in server actionsauth.api.*methods: For server-side operations (RSC, server actions)authClient.*methods: For client-side operations- Database: Configure a database adapter (SQLite, PostgreSQL, MySQL, Turso, etc.) in the
authinstance - Route Protection: Use the proxy file (or middleware in older Next.js versions) to protect routes
For a complete working example, check out the demo Next.js project in the repository!
END OF POST