@next-safe-action/adapter-better-auth
v0.1.6
Published
Better Auth adapter for next-safe-action.
Downloads
1,820
Maintainers
Readme
This adapter offers a way to seamlessly integrate next-safe-action with Better Auth. It provides a betterAuth() function that fetches the session, blocks unauthenticated requests, and injects fully-typed { user, session } data into the action context.
Requirements
- Next.js >=
15.1.0 - next-safe-action >=
8.4.0 - better-auth >=
1.5.0
Installation
npm i next-safe-action better-auth @next-safe-action/adapter-better-authQuick start
1. Set up Better Auth
Create your Better Auth server instance:
// src/lib/auth.ts
import { betterAuth } from "better-auth";
export const auth = betterAuth({
// ...your config (database, plugins, etc.)
});2. Create an authenticated action client
// src/lib/safe-action.ts
import { createSafeActionClient } from "next-safe-action";
import { betterAuth } from "@next-safe-action/adapter-better-auth";
import { auth } from "./auth";
export const actionClient = createSafeActionClient();
export const authClient = actionClient.use(betterAuth(auth));3. Use it in your actions
// src/app/actions.ts
"use server";
import { z } from "zod";
import { authClient } from "@/lib/safe-action";
export const updateProfile = authClient
.inputSchema(z.object({ name: z.string().min(1) }))
.action(async ({ parsedInput, ctx }) => {
// ctx.auth.user and ctx.auth.session are fully typed
const userId = ctx.auth.user.id;
await db.user.update({
where: { id: userId },
data: { name: parsedInput.name },
});
return { success: true };
});How it works
betterAuth() creates a pre-validation middleware for the safe action client's .use() chain:
- Fetches the session by calling
auth.api.getSession({ headers: await headers() }) - Blocks unauthenticated requests by calling
unauthorized()fromnext/navigationwhen no session exists - Injects typed context by passing
{ auth: { user, session } }tonext(), merging it into the action context
unauthorized() and auth interrupts
The default behavior uses unauthorized() from next/navigation, which requires experimental.authInterrupts in your Next.js configuration:
// next.config.ts
import type { NextConfig } from "next";
const nextConfig: NextConfig = {
experimental: {
authInterrupts: true,
},
};
export default nextConfig;Custom authorization
Pass an authorize callback to customize the authorization flow. The session is pre-fetched and passed to the callback:
import { unauthorized } from "next/navigation";
import { betterAuth } from "@next-safe-action/adapter-better-auth";
import { auth } from "./auth";
// Role-based access
export const adminClient = actionClient.use(
betterAuth(auth, {
authorize: ({ authData, next }) => {
if (!authData || authData.user.role !== "admin") {
unauthorized();
}
return next({ ctx: { auth: authData } });
},
})
);authorize callback parameters
authData: the pre-fetched session data ({ user, session } | null)ctx: the current action context from preceding middlewarenext: call this to continue the middleware chain, pass{ ctx }to inject context
Server Action cookies
If your actions call Better Auth functions that set cookies (e.g. signInEmail, signUpEmail), add the nextCookies() plugin to your Better Auth instance. Refer to the Better Auth documentation for more details.
// src/lib/auth.ts
import { betterAuth } from "better-auth";
import { nextCookies } from "better-auth/next-js";
export const auth = betterAuth({
// ...your config
plugins: [
// ...other plugins
nextCookies(), // must be the last plugin in the array
],
});API reference
betterAuth(auth, opts?)
Creates a middleware function for use with the safe action client's .use() method.
Parameters:
auth: the Better Auth server instance (return value ofbetterAuth())opts?: optional object with anauthorizecallback for custom authorization logic
Returns: a middleware function compatible with .use()
Exported types
BetterAuthContext<Options>: the context shape added by the middleware ({ auth: { user, session } })AuthorizeFn<Options, NextCtx>: theauthorizecallback signatureBetterAuthOpts<Options, NextCtx>: the options object type forbetterAuth
Documentation
For full documentation, visit next-safe-action.dev/docs/integrations/better-auth.
Preview releases powered by pkg.pr.new
License
MIT
