@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).*)"],
};