Next.js Adapter
Use Nevr with Next.js App Router.
Scaffolding (Recommended)
npm create nevr@latest my-app --template nextjsThis creates a complete Next.js project with Nevr pre-configured.
Manual Installation
npm install nevr next react react-dom
npm install -D @types/react @types/react-dom typescriptSetup
1. Config (lib/nevr.config.ts)
import { defineConfig } from "nevr"
import * as entities from "./entities"
export const config = defineConfig({
database: "sqlite",
entities: Object.values(entities).filter(e => e && typeof e === "object"),
plugins: [],
})
export default config2. Create Nevr Instance (lib/nevr.ts)
import { nevr } from "nevr"
import { prisma } from "nevr/drivers/prisma"
import { PrismaClient } from "@prisma/client"
import { config } from "./nevr.config"
const db = new PrismaClient()
const driver = prisma(db)
export const api = nevr({ ...config, driver })2. Create API Route Handler
// app/api/[...nevr]/route.ts
import { toNextHandler } from "nevr/adapters/nextjs"
import { api } from "@/lib/nevr"
export const { GET, POST, PUT, PATCH, DELETE } = toNextHandler(api)That's it! Your API is now available at /api/*.
With Authentication
1. Add Auth Plugin
// lib/nevr.config.ts
import { defineConfig } from "nevr"
import { auth } from "nevr/plugins/auth"
import * as entities from "./entities"
export const config = defineConfig({
database: "sqlite",
entities: Object.values(entities).filter(e => e && typeof e === "object"),
plugins: [
auth({
// Secret is auto-read from NEVR_AUTH_SECRET env variable
emailAndPassword: { enabled: true },
}),
],
})
export default config// lib/nevr.ts
import { nevr } from "nevr"
import { prisma } from "nevr/drivers/prisma"
import { PrismaClient } from "@prisma/client"
import { nextCookies } from "nevr/adapters/nextjs"
import { config } from "./nevr.config"
const db = new PrismaClient()
const driver = prisma(db)
export const api = nevr({
...config,
driver,
plugins: [...(config.plugins ?? []), nextCookies()],
})2. Use Session Auth in Route Handler
// app/api/[...nevr]/route.ts
import { toNextHandler, sessionAuth } from "nevr/adapters/nextjs"
import { api } from "@/lib/nevr"
export const { GET, POST, PUT, PATCH, DELETE } = toNextHandler(api, {
getUser: sessionAuth(api),
debugLogs: process.env.NODE_ENV !== "production",
})3. Access Session in Server Components
// app/dashboard/page.tsx
import { getServerSession } from "nevr/adapters/nextjs"
import { redirect } from "next/navigation"
import { api } from "@/lib/nevr"
export default async function Dashboard() {
const session = await getServerSession(api)
if (!session) {
redirect("/login")
}
return (
<div>
<h1>Dashboard</h1>
<p>Welcome, {session.user.name}!</p>
</div>
)
}4. Add Middleware for Route Protection
// middleware.ts
import { withNevrMiddleware } from "nevr/adapters/nextjs"
export default withNevrMiddleware({
protectedRoutes: ["/dashboard/*", "/settings/*"],
publicRoutes: ["/", "/login", "/register", "/api/auth/*"],
loginPath: "/login",
})
export const config = {
matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
}API Reference
toNextHandler(api, options?)
Creates Next.js App Router route handlers.
import { toNextHandler } from "nevr/adapters/nextjs"
export const { GET, POST, PUT, PATCH, DELETE } = toNextHandler(api, {
// Get authenticated user from request
getUser: sessionAuth(api),
// Enable debug logging
debugLogs: true,
// Base path to strip (default: "/api")
basePath: "/api",
})nextCookies(options?)
Plugin for handling cookies in Server Components.
import { nextCookies } from "nevr/adapters/nextjs"
const api = nevr({
// ...config,
plugins: [...(config.plugins ?? []), nextCookies()],
})getServerSession(api, options?)
Get session in Server Components.
import { getServerSession } from "nevr/adapters/nextjs"
const session = await getServerSession(api, {
cookieName: "nevr.session_token", // default
})
// session = { user, expiresAt, token } or nullrequireSession(api, options?)
Require authentication, redirects if not logged in.
import { requireSession } from "nevr/adapters/nextjs"
// Throws redirect if not authenticated
const session = await requireSession(api, {
redirectTo: "/login", // default
})sessionAuth(api, options?)
Creates a getUser function that resolves the authenticated user from each request. It reads the session cookie (or Authorization: Bearer header), looks up the session in the database, checks expiry, and returns the user.
import { sessionAuth } from "nevr/adapters/nextjs"
toNextHandler(api, {
getUser: sessionAuth(api, {
cookieName: "nevr.session_token", // default
}),
})The flow:
- User signs in → auth plugin creates a session and sets a
nevr.session_tokencookie - User makes a request →
sessionAuth(api)reads the cookie, finds the session, returns theUser - Nevr checks entity rules (e.g.,
"authenticated","owner") against that user
| Option | Type | Default | Description |
|---|---|---|---|
cookieName | string | "nevr.session_token" | Cookie name to read |
Note
Unlike Express/Hono where sessionAuth takes a driver, the Next.js version takes the api instance and calls api.getDriver() internally.
withNevrMiddleware(options)
Create Next.js middleware for route protection.
import { withNevrMiddleware, createMatcher } from "nevr/adapters/nextjs"
export default withNevrMiddleware({
// Routes requiring authentication
protectedRoutes: ["/dashboard/*"],
// Always accessible routes
publicRoutes: ["/", "/login"],
// Redirect destination
loginPath: "/login",
// Session cookie name
cookieName: "nevr.session_token",
})
// Helper for matcher config
export const config = createMatcher({
exclude: ["api/public"],
})Pages Router (Legacy)
For Next.js Pages Router (legacy):
// pages/api/[...nevr].ts
import { toApiHandler, pagesSessionAuth } from "nevr/adapters/nextjs"
import { api } from "@/lib/nevr"
export default toApiHandler(api, {
cors: true,
getUser: pagesSessionAuth(api),
})Project Structure
my-nextjs-app/
├── app/
│ ├── api/
│ │ └── [...nevr]/
│ │ └── route.ts # Nevr API handler
│ ├── dashboard/
│ │ └── page.tsx # Protected page
│ ├── layout.tsx
│ └── page.tsx
├── lib/
│ ├── nevr.ts # Nevr instance
│ ├── nevr.config.ts # Nevr config
│ └── entities/
│ ├── user.ts
│ └── post.ts
├── middleware.ts # Route protection
└── package.jsonEdge Runtime
The Next.js adapter uses the Web Fetch API, making it compatible with Edge Runtime:
// app/api/[...nevr]/route.ts
export const runtime = "edge"
export const { GET, POST, PUT, PATCH, DELETE } = toNextHandler(api)Tips
- Always add
nextCookies()plugin when using auth with Server Components - Use
sessionAuth()for API routes to automatically validate sessions - Use
getServerSession()in Server Components for server-side auth checks - Use
withNevrMiddleware()for route protection - faster than checking in every page - Define
nevr.config.tsfor CLI commands likenpx nevr generate
