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 .
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 instance. You can name the file anything you want. Here we are creating client.ts
file inside the lib/
directory.
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.
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
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 >
)
}
You can use the authMiddleware
to protect your routes. It's a wrapper around the Next.js middleware.
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" ],
};