KeyloomKeyloom
Keyloom Auth is currently in beta. Feedback and contributions are welcome!
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

  1. Install packages and create keyloom.config.ts (see Installation)
  2. Add an auth handler route under app/api/auth/[...keyloom]/route.ts
  3. Add middleware for route protection
app/api/auth/[...keyloom]/route.ts
import { createNextHandler } from "@keyloom/nextjs";
import config from "@/keyloom.config";

export const { GET, POST } = createNextHandler(config);
middleware.ts
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 session
  • POST /api/auth/signin/:provider - start OAuth login
  • GET /api/auth/callback/:provider - OAuth callback
  • POST /api/auth/logout - end session
  • GET /api/auth/jwks - JWKS for JWT verification
  • POST /api/auth/magic-link/request - request magic link (passwordless auth)
  • GET /api/auth/magic-link/verify - verify magic link from email
  • POST /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].ts exporting a default handler from createNextApiHandler.
pages/api/auth/[...keyloom].ts
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.

app/dashboard/page.tsx
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 callbacks
  • session.strategy - "jwt" or "database"
  • cookie - name, path, sameSite, secure
  • providers - OAuth/OpenID providers
  • adapter - 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 }
  • POST /api/auth/signin/:provider
    • 302 redirect to provider (query callbackUrl optional)
  • GET /api/auth/callback/:provider
    • 302 redirect to callbackUrl (or default)
    • Sets cookies for session (DB) or JWTs (JWT strategy)
  • POST /api/auth/logout
    • 200 { ok: true } and clears auth cookies
  • GET /api/auth/jwks
    • 200 { keys: Jwk[] }

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

app/dashboard/page.tsx
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

Next steps

  • Wire middleware and handler in your app
  • Configure one provider and test the full sign-in flow

How is this guide?