@bulwarkauth/nextjs
Next.js SDK for Bulwark — middleware, Server Component helpers, cookie-based session management, and route handler utilities.
Installation
npm install @bulwarkauth/nextjs
# or
pnpm add @bulwarkauth/nextjs
Entry points
| Import path | Use for |
|-------------|---------|
| @bulwarkauth/nextjs | Client components ("use client") and provider |
| @bulwarkauth/nextjs/server | Server Components, Server Actions, route handlers |
| @bulwarkauth/nextjs/middleware | middleware.ts |
Provider
CookieAwareBulwarkProvider
A wrapper around BulwarkProvider that stores tokens in HTTP cookies so Server Components can read them without client-side hydration.
Add it to your root layout:
// app/layout.tsx
import { CookieAwareBulwarkProvider } from "@bulwarkauth/nextjs";
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
<CookieAwareBulwarkProvider publishableKey="pk_live_...">
{children}
</CookieAwareBulwarkProvider>
</body>
</html>
);
}
Props
| Prop | Type | Required | Description |
|------|------|----------|-------------|
| publishableKey | string | Yes | Your pk_live_ or pk_test_ key |
Re-exports from @bulwarkauth/react
The following are re-exported directly from @bulwarkauth/nextjs and work identically to their React counterparts:
Components: SignIn, SignUp, UserButton, UserProfile
Hooks: useAuth, useMFA, usePasskey, useBulwark, useAppConfig
All must be used inside a Client Component ("use client").
// app/login/page.tsx — this is a Server Component, SignIn renders client-side
import { SignIn } from "@bulwarkauth/nextjs";
export default function LoginPage() {
return <SignIn signUpUrl="/signup" />;
}
Server helpers (@bulwarkauth/nextjs/server)
All server helpers read the session from cookies set by CookieAwareBulwarkProvider. They are safe to call in Server Components, Server Actions, and route handlers.
auth()
Returns { user, session } or { user: null, session: null } if not authenticated. The primary helper for Server Components.
// app/dashboard/page.tsx
import { auth } from "@bulwarkauth/nextjs/server";
import { redirect } from "next/navigation";
export default async function DashboardPage() {
const { user } = await auth();
if (!user) {
redirect("/login");
}
return <h1>Welcome, {user.display_name}</h1>;
}
getSession()
Returns the raw session object (access token, refresh token, expiry) or null.
import { getSession } from "@bulwarkauth/nextjs/server";
const session = await getSession();
// session.accessToken, session.refreshToken, session.expiresAt
getUser()
Returns the User object or null. Equivalent to (await auth()).user.
import { getUser } from "@bulwarkauth/nextjs/server";
const user = await getUser();
currentUser()
Returns the User object. Throws BulwarkAuthError if not authenticated. Use when you want to assert that authentication is present.
import { currentUser } from "@bulwarkauth/nextjs/server";
// In a Server Action:
export async function updateProfile(data: FormData) {
"use server";
const user = await currentUser(); // throws if signed out
// ...
}
requireSession()
Returns { user, session }. Throws BulwarkAuthError if not authenticated. Use in Server Actions and route handlers where a missing session is a programming error.
import { requireSession } from "@bulwarkauth/nextjs/server";
export async function GET() {
const { user } = await requireSession();
return Response.json({ id: user.id });
}
Route handler wrapper
withBulwarkAuth(handler, options?)
Wraps a Next.js route handler to require authentication. Injects the authenticated user into the handler.
// app/api/profile/route.ts
import { withBulwarkAuth } from "@bulwarkauth/nextjs/server";
export const GET = withBulwarkAuth(async (req, { user }) => {
return Response.json({ id: user.id, email: user.email });
});
// Require a specific role:
export const DELETE = withBulwarkAuth(
async (req, { user }) => {
// ...
return new Response(null, { status: 204 });
},
{ roles: ["admin"] }
);
Options
| Option | Type | Description |
|--------|------|-------------|
| roles | string[] | Roles required to access this handler. Returns 403 if any role is missing |
Middleware
createBulwarkMiddleware(config)
Creates a Next.js middleware function that protects routes and redirects unauthenticated requests to the login page.
// middleware.ts
import { createBulwarkMiddleware } from "@bulwarkauth/nextjs/middleware";
export default createBulwarkMiddleware({
protectedPaths: ["/dashboard", "/settings", "/api/private"],
publicPaths: ["/", "/login", "/signup", "/api/auth"],
loginPath: "/login",
requiredRoles: [], // optional global role requirement
});
export const config = {
matcher: ["/((?!_next|static|favicon.ico).*)"],
};
Config options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| protectedPaths | string[] | [] | Paths (prefix-matched) that require authentication |
| publicPaths | string[] | [] | Paths explicitly exempt from protection |
| loginPath | string | "/login" | Redirect destination for unauthenticated requests |
| requiredRoles | string[] | [] | Roles required on all protected paths |
Paths are prefix-matched. /dashboard matches /dashboard, /dashboard/settings, etc.
Cookie management
These utilities are used internally by CookieAwareBulwarkProvider but are exported for advanced use cases such as custom login flows in route handlers.
import {
setAuthCookies,
clearAuthCookies,
getTokenFromCookies,
} from "@bulwarkauth/nextjs/server";
setAuthCookies(response, tokens)
Sets bulwark_access_token and bulwark_refresh_token cookies on a Response object.
import { setAuthCookies } from "@bulwarkauth/nextjs/server";
// In a route handler after a custom login:
export async function POST(req: Request) {
const { accessToken, refreshToken } = await performLogin(req);
const response = Response.json({ ok: true });
setAuthCookies(response, { accessToken, refreshToken });
return response;
}
clearAuthCookies(response)
Clears auth cookies (sets them with maxAge: 0). Called automatically by UserButton sign-out.
getTokenFromCookies()
Returns the raw access token string from the current request's cookies, or null. Useful for passing the token to external services.
Example: complete middleware.ts
import { createBulwarkMiddleware } from "@bulwarkauth/nextjs/middleware";
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export default createBulwarkMiddleware({
protectedPaths: [
"/dashboard",
"/settings",
"/api/v1",
],
publicPaths: [
"/",
"/login",
"/signup",
"/api/auth",
"/api/health",
],
loginPath: "/login",
});
export const config = {
// Run on all routes except Next.js internals and static files
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};