Nextjs
Next.js Handler (API routes)
The createNextHandler API and the built-in endpoints exposed under /api/auth/[[...keyloom]].
Handler: createNextHandler
Exports GET/POST handlers for the Keyloom API routes in the App Router.
import { createNextHandler } from "@keyloom/nextjs";
import config from "@/keyloom.config";
export const { GET, POST } = createNextHandler(config);Endpoints
The handler maps these endpoints:
GET
GET /api/auth/session→{ session, user }(DB or JWT strategy)GET /api/auth/csrf→ issues CSRF token and sets__keyloom_csrfGET /api/auth/oauth/:provider/start→ redirects to providerGET /api/auth/oauth/:provider/callback→ handles provider callback, sets session cookie, redirects
POST
POST /api/auth/oauth/:provider/callback→ form_post callback (Apple etc.)POST /api/auth/register→{ userId, requiresVerification }POST /api/auth/login→ sets session cookie, returns{ sessionId }POST /api/auth/logout→ clears session cookie,{ ok: true }POST /api/auth/password/request→ issues verification token (store via adapter),{ ok: true }POST /api/auth/password/reset→ uses token, updates credential,{ ok: true }POST /api/auth/email/verify→ uses token, setsemailVerified,{ ok: true }
Configuration Notes
config.adapteris used for user/session/token storageconfig.secrets.authSecretis required to seal OAuth state and hash verification tokensconfig.baseUrlis used to build OAuth callback URLsconfig.session.ttlMinutesinfluences login session TTL (database strategy)
Hooks and Plugins
config.hooks.onRequest({ kind, req })→ optionally return aResponseto short-circuit (deny/redirect/metrics)config.plugins→ array of additional{ method: 'GET'|'POST'; path: RegExp; handler(req, ctx) }
JWT Strategy
When config.sessionStrategy === 'jwt' (or equivalent env), the handler will:
- For
GET /session, inferjwksUrland verify the access token from cookies orAuthorizationheader - For login, you typically use
@keyloom/serverto issue tokens and set__keyloom_access/__keyloom_refresh
See the JWT page and jwt-server utilities for details.
Error Handling
- 404
{ error: 'not_found' }for unknown paths - 405
{ error: 'method_not_allowed' }for unsupported methods - 403
{ error: 'csrf' }if CSRF validation fails for state-changing POSTs - 400
{ error: 'invalid_request'|'invalid_token' }for malformed inputs
Example: Custom provider start
// /app/sign-in/page.tsx
function SignInPage() {
return (
<a href="/api/auth/oauth/github/start?callbackUrl=/dashboard">
Continue with GitHub
</a>
);
}Request/response schemas (summary)
| Method | Path | Success | Errors |
|---|---|---|---|
| GET | /api/auth/session | 200 { user, session } or { user: null, session: null } | 401 { error: 'unauthorized' } |
| GET | /api/auth/csrf | 200 { token } and Set-Cookie | - |
| POST | /api/auth/login | 200 { sessionId } and Set-Cookie | 400 { error: 'invalid_request' } |
| POST | /api/auth/logout | 200 { ok: true } and clears cookies | - |
| GET/POST | /api/auth/oauth/:provider/(start|callback) | 302 Redirect with cookies set on success | 400/401 provider error details |
| GET | /api/auth/jwks | 200 { keys: Jwk[] } | - |
See Server overview for deeper schemas.
Example: custom start and callback
import { createNextHandler } from "@keyloom/nextjs";
import cfg from "@/keyloom.config";
export const { GET, POST } = createNextHandler(cfg, {
onRequest: ({ kind, req }) => {
// add logging, rate limiting, or A/B testing here
},
});Performance and edge notes
- Prefer App Router route handlers for streaming and simpler responses
- Keep handlers stateless; use adapter for persistence
- JWT strategy minimizes DB lookups on /session
- Cache JWKS at the server boundary
Troubleshooting
- CSRF error on POST: ensure CSRF cookie present, same-site rules, and token header/body included
- 405 errors: check you export both GET and POST and match your route file path
- Provider callback failure: confirm provider app settings and exact callback URL
See also
- Next.js overview: /docs/nextjs/overview
- Middleware: /docs/nextjs/middleware
- Core JWT: /docs/core/jwt
Next steps
- Add a sign-in page with provider start links
- Wire logout and session display in your layout
How is this guide?