Next.js
Mount Radon in a Next.js App Router app — one catch-all route, plus helpers to read the user in route handlers, server components, and middleware.
Radon's Next.js integration is one handler you export from a catch-all route,
plus helpers to read the current user anywhere you have a Request.
Prerequisites
A configured auth instance (Installation) and at least
one auth method enabled. App Router (the app/ directory).
1. Mount the auth routes
Create a catch-all route and export the handler for both GET and POST.
import { radonNextHandler } from "@radonsdk/auth/integrations/next";
import { auth } from "@/lib/auth";
const handler = radonNextHandler(auth, { basePath: "/api/auth" });
export const GET = handler;
export const POST = handler;That single file serves every auth route under /api/auth (see each
method for its routes).
Handler options
radonNextHandler(auth, {
basePath: "/api/auth", // must match the route folder
cookieName: "acme_session", // default "radon_session"
cookieOptions: { domain: ".acme.com", sameSite: "lax" },
successRedirect: "/dashboard", // after magic-link / OAuth callback
failureRedirect: "/signin?error=1",
});2. Read the user in a route handler
getUserFromRequest verifies the session cookie and loads the user, or returns
null.
import { getUserFromRequest } from "@radonsdk/auth/integrations/next";
import { auth } from "@/lib/auth";
export async function GET(req: Request) {
const user = await getUserFromRequest(auth, req);
if (!user) return new Response("Unauthorized", { status: 401 });
return Response.json({ user });
}3. Read the user in a Server Component
Server Components don't get a Request, so build one from next/headers:
import { headers } from "next/headers";
import { getUserFromRequest } from "@radonsdk/auth/integrations/next";
import { redirect } from "next/navigation";
import { auth } from "@/lib/auth";
export default async function Dashboard() {
const req = new Request("http://local/", { headers: await headers() });
const user = await getUserFromRequest(auth, req);
if (!user) redirect("/signin");
return <h1>Welcome, {user.email}</h1>;
}4. Gate routes in middleware
For a cheap check with no database hit, getSessionClaims verifies just the
JWT signature and returns the claims (claims.sub is the user id).
import { NextResponse } from "next/server";
import { getSessionClaims } from "@radonsdk/auth/integrations/next";
import { auth } from "@/lib/auth";
export function middleware(req: Request) {
const claims = getSessionClaims(auth, req);
if (!claims) return NextResponse.redirect(new URL("/signin", req.url));
return NextResponse.next();
}
export const config = { matcher: ["/dashboard/:path*"] };Claims vs. user
getSessionClaims is signature-only (fast, edge-safe) — use it to gate. When you
need the actual user record, use getUserFromRequest (one DB read).
CSRF for your own endpoints
Radon's auth routes are protected, but for your own state-changing POST routes you can use the double-submit helpers:
import { issueCsrfToken, verifyCsrfToken } from "@radonsdk/auth/integrations/next";