Nextjs
Next.js Integration
Overview of the Keyloom Next.js integration - route handlers, middleware, sessions, and edge compatibility.
Next.js Integration
This guide covers how to use Keyloom with Next.js, including route handlers, middleware, session reading on the server, and edge compatibility.
Packages
@keyloom/nextjs- framework bindings for Next.js@keyloom/core- core engine and config
Quick start
- Install packages and create
keyloom.config.ts(see Installation) - Add an auth handler route under
app/api/auth/[...keyloom]/route.ts - Add middleware for route protection
import { createNextHandler } from "@keyloom/nextjs";
import config from "@/keyloom.config";
export const { GET, POST } = createNextHandler(config);import { createAuthMiddleware } from "@keyloom/nextjs/middleware";
import config from "@/keyloom.config";
export default createAuthMiddleware(config, {
publicRoutes: ["/", "/sign-in"],
});
export const config = {
matcher: ["/((?!_next|.*\\.(?:ico|png|jpg|svg|css|js|map)).*)"],
};Built-in routes
When you export { GET, POST } from createNextHandler, the following endpoints are available under your auth route (by default /api/auth):
GET /api/auth/session- get current sessionPOST /api/auth/signin/:provider- start OAuth loginGET /api/auth/callback/:provider- OAuth callbackPOST /api/auth/logout- end sessionGET /api/auth/jwks- JWKS for JWT verificationPOST /api/auth/magic-link/request- request magic link (passwordless auth)GET /api/auth/magic-link/verify- verify magic link from emailPOST /api/auth/magic-link/verify- verify magic link programmatically
See the Handler reference for full schemas and examples.
App Router vs Pages Router
- App Router is fully supported with Route Handlers.
- Pages Router can use API routes:
pages/api/auth/[...keyloom].tsexporting a default handler fromcreateNextApiHandler.
import { createNextApiHandler } from "@keyloom/nextjs/pages";
import config from "@/keyloom.config";
export default createNextApiHandler(config);Edge compatibility
- The middleware and session verification work on Edge runtime when your configuration and adapter are edge-safe. Use the memory adapter or a compatible KV/HTTP adapter on edge.
Reading the session on the server
Use the server utilities to read the session in server components, actions, or route handlers.
import { getServerSession } from "@keyloom/nextjs";
import config from "@/keyloom.config";
export default async function Page() {
const session = await getServerSession(config);
if (!session) return <Redirect href="/sign-in" />;
return <div>Hello {session.user.name}</div>;
}Configuration overview
Pass your defineKeyloom config to createNextHandler and the middleware. Common options:
baseUrl- external base URL for callbackssession.strategy-"jwt"or"database"cookie- name, path, sameSite, secureproviders- OAuth/OpenID providersadapter- database adapter when using database sessions
See Configuration for the full reference.
Request/response schemas (summary)
- GET /api/auth/session
- 200
{ user: { id, email?, name? }, session: { id, userId, expiresAt } } | { user: null, session: null }
- 200
- POST /api/auth/signin/:provider
- 302 redirect to provider (query
callbackUrloptional)
- 302 redirect to provider (query
- GET /api/auth/callback/:provider
- 302 redirect to
callbackUrl(or default) - Sets cookies for session (DB) or JWTs (JWT strategy)
- 302 redirect to
- POST /api/auth/logout
- 200
{ ok: true }and clears auth cookies
- 200
- GET /api/auth/jwks
- 200
{ keys: Jwk[] }
- 200
See Handler page for full schemas.
Edge runtime notes
- Middleware supports Edge, but heavy verification can be slow; prefer server verification for complex checks
- Use JWT strategy for Edge; database sessions require serverless-compatible adapters
Server session reading with error handling
import { getServerSession } from "@keyloom/nextjs";
import cfg from "@/keyloom.config";
export default async function Page() {
try {
const session = await getServerSession(cfg);
if (!session) return <a href="/sign-in">Sign in</a>;
return <div>Hello {session.user?.name ?? session.user?.id}</div>;
} catch (e) {
console.error("session_error", e);
return <div>Temporary issue. Please retry.</div>;
}
}Performance tips
- Do not fetch session on client if already checked in middleware
- Cache public JWKS responses for 5-10 minutes
- Avoid large route matchers in middleware; prefer concise patterns
- Minimize provider scopes to reduce OAuth latency
Troubleshooting
- Infinite redirects after sign-in: verify
baseUrl, callback URL, and cookie domain/path - 401 on protected pages: ensure middleware matcher excludes assets and includes your paths
- CSRF errors on POST: ensure CSRF token is included or disable where appropriate for OAuth redirects
See also
- Handler reference: /docs/nextjs/handler
- Middleware: /docs/nextjs/middleware
- Core JWT: /docs/core/jwt
Next steps
- Wire middleware and handler in your app
- Configure one provider and test the full sign-in flow
How is this guide?