Docs

Next JS integration

Better Auth can be easily integrated with Next.js. It'll also comes with utilities to make it easier to use Better Auth with Next.js.

Before you start, make sure you have a Better Auth instance configured. If you haven't done that yet, check out the installation.

Create API Route

We need to mount the handler to an API route. Create a route file inside /api/auth/[...all] directory. And add the following code:

api/auth/[...all]/route.ts
import { auth } from "@/lib/auth";
import { toNextJsHandler } from "better-auth/next-js";
 
export const { GET, POST } = toNextJsHandler(auth.handler);

You can change the path on your better-auth configuration but it's recommended to keep it as /api/auth/[...all]

Create a client

Create a client instance. You can name the file anything you want. Here we are creating client.ts file inside the lib/ directory.

client.ts
import { createAuthClient } from "better-auth/react" // make sure to import from better-auth/react
 
export const client = createAuthClient({
    //you can pass client configuration here
})

Once you have created the client, you can use it to sign up, sign in, and perform other actions. Some of the actinos are reactive. The client use nano-store to store the state and re-render the components when the state changes.

The client also uses better-fetch to make the requests. You can pass the fetch configuration to the client.

RSC and Server actions

The api object exported from the auth instance contains all the actions that you can perform on the server. Every endpoint made inside Better Auth is a invokable as a function. Including plugins endpoints.

Example: Getting Session on a server action

server.ts
import { auth } from "@/lib/auth"
import { headers } from "next/headers"
 
const someAuthenticatedAction = async () => {
    "use server";
    const session = await auth.api.getSession({
        headers: headers()
    })
};

Example: Getting Session on a RSC

import { auth } from "@/lib/auth"
import { headers } from "next/headers"
 
export async function ServerComponent() {
    const session = await auth.api.getSession({
        headers: headers()
    })
    if(!session) {
        return <div>Not authenticated</div>
    }
    return (
        <div>
            <h1>Welcome {session.user.name}</h1>
        </div>
    )
}

Middleware

You can use the authMiddleware to protect your routes. It's a wrapper around the Next.js middleware.

middleware.ts
import { authMiddleware } from "better-auth/next-js"
 
export default authMiddleware({
    redirectTo: "/sign-in" // redirect to this path if the user is not authenticated
})
 
export const config = {
  matcher: ['/dashboard/:path*'],
}

you can also pass custom redirect function

import { authMiddleware } from "better-auth/next-js";
import { NextResponse } from "next/server";
 
export default authMiddleware({
	customRedirect: async (session, request) => {
		const baseURL = request.nextUrl.origin;
		if (request.nextUrl.pathname === "/sign-in" && session) {
			return NextResponse.redirect(new URL("/dashboard", baseURL));
		}
		if (request.nextUrl.pathname === "/dashboard" && !session) {
			return NextResponse.redirect(new URL("/sign-in", baseURL));
		}
		return NextResponse.next();
	},
});
 
export const config = {
	matcher: ["/dashboard", "/sign-in"],
};

On this page

Edit on GitHub