Nextjs
Middleware
Protect routes and attach session context using Keyloom's Next.js middleware.
Middleware
Use Keyloom's middleware to protect pages and APIs, attach session context, and optionally run verification at the edge.
import { createAuthMiddleware } from "@keyloom/nextjs/middleware";
import config from "@/keyloom.config";
export default createAuthMiddleware(config, {
publicRoutes: ["/", "/sign-in", "/api/health"],
verifyAtEdge: false,
// routes: compiledManifest, // optional - for declarative gating
});
export const config = {
matcher: ["/((?!_next|.*\\.(?:ico|png|jpg|svg|css|js|map)).*)"],
};Options
publicRoutes: string[]- paths that do not require authverifyAtEdge: boolean- when true, verify JWT/session at the edgeroutes- optional manifest to declare which routes require which roles
Behavior
- Reads the incoming cookie token
- Optionally verifies at edge and attaches lightweight auth hints
- Redirects to your sign-in page if a protected page is accessed without a valid session
- Works in both app and pages router
Patterns
- Use
publicRoutesto allow public marketing pages - Prefer server-side gating for sensitive APIs as an additional layer
- Consider
verifyAtEdge: truewhen you need early blocking and are using an edge-safe strategy (JWT + edge-safe adapter)
Troubleshooting
- Ensure your
matcherexcludes Next.js internals and static assets - If redirects loop, verify
baseUrland cookie domain/path settings - In development, set
cookie.secure: false
Prerequisites
keyloom.config.tsconfigured- Public sign-in route defined and included in
publicRoutes - Correct
matcherexcluding Next internals and asset files
Advanced route matching
export const config = {
matcher: [
// protect everything under /app except public
"/app/:path*",
// protect APIs except health
"/api/(?!health).*",
],
};Edge runtime compatibility
- Works in Edge; avoid heavy DB calls in middleware
- Use
verifyAtEdge: trueonly with JWT strategy and cached JWKS - For APIs requiring DB, verify on the server handler instead
Error handling patterns
- For pages: redirect to
/sign-inwhen unauthenticated - For APIs: return JSON
{ error: 'unauthorized' }with 401
export default createAuthMiddleware(config, {
publicRoutes: ["/api/health"],
onUnauthorized: (ctx) => {
if (ctx.isApi)
return new Response(JSON.stringify({ error: "unauthorized" }), {
status: 401,
});
return Response.redirect(new URL("/sign-in", ctx.req.url));
},
});Performance tips
- Keep
publicRoutesprecise to avoid extra work - Prefer a single lightweight cookie read and short-circuit where possible
- Avoid per-request remote JWKS fetch; cache JWKS in memory
See also
- Overview: /docs/nextjs/overview
- Handler: /docs/nextjs/handler
- RBAC: /docs/core/rbac
Next steps
- Add route-level role checks with server-side
withRole
How is this guide?