Live Reference — App Router + Pages Router|v15.1 · v14 · v13

Every Next.js API, instantly.

Route handlers, middleware hooks, server actions — mapped to exact code. No paragraphs. No blog posts. Just the line you need at 2 a.m. when production is down.

›_
1,247
API endpoints documented
0.4s
avg. lookup time
12 min ago
last updated
13–15
Next.js versions covered

01
App Router

Route Handlers

NextRequest, dynamic params, HTTP methods, and caching behavior — the foundation of every API in the App Router.

✕ ERRORProperty 'searchParams' does not exist on type 'Request'. Use request.nextUrl.searchParams
BROKEN
// ❌ Using native Request — searchParams not available
export async function GET(request: Request) {
const query = request.searchParams.get('q') // undefined!
return Response.json({ error: 'broken' })
}
↓ FIX
app/api/search/route.tsCORRECT
// app/api/search/route.ts
import { NextRequest } from 'next/server';
export async function GET(request: NextRequest) {
const searchParams = request.nextUrl.searchParams
const query = searchParams.get('q') // ✓ works
const page = searchParams.get('page') ?? '1'
return Response.json({ query, page })
}

NextRequest extends the native Request with .nextUrl, giving you a fully parsed URL object including searchParams. Always import from next/server, not from the web standard.

#NextRequest#searchParams#app-router
Quick Reference
GETRead data, dynamic by default in v15200
POSTCreate resource, return 201201
PUTReplace resource200
PATCHPartial update200
DELETERemove resource, return 204 (no body)204
OPTIONSCORS preflight — set Access-Control headers200

02
Edge Runtime

Middleware & Edge Runtime

The most error-prone surface in Next.js. Edge Runtime restrictions, matcher config, and auth patterns — all with exact fixes.

⚠ EDGEMiddleware runs on Edge Runtime — no Node.js crypto, fs, or path. No headers() from next/headers. Read from request.headers directly.
✕ ERRORError: The package 'jsonwebtoken' requires Node.js APIs that are not available in the Edge Runtime.
BROKEN
// middleware.ts ❌ — jsonwebtoken uses Node.js crypto
import jwt from 'jsonwebtoken';
export function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value
const decoded = jwt.verify(token!, process.env.JWT_SECRET!)
// ↑ throws at runtime: crypto not available on Edge
}
↓ FIX
middleware.tsCORRECT
// middleware.ts — use jose (Edge-compatible)
import { jwtVerify } from 'jose';
import { NextRequest, NextResponse } from 'next/server';
export async function middleware(request: NextRequest) {
const token = request.cookies.get('token')?.value
if (!token) return NextResponse.redirect(new URL('/login', request.url))
try {
const secret = new TextEncoder().encode(process.env.JWT_SECRET!)
await jwtVerify(token, secret) // ✓ Edge-compatible
return NextResponse.next()
} catch {
return NextResponse.redirect(new URL('/login', request.url))
}
}

Edge Runtime runs in a browser-like V8 environment — Node.js crypto, fs, and path are unavailable. Replace jsonwebtoken with jose, which uses the Web Crypto API and runs anywhere.

#edge-runtime#jose#jwt#middleware
Runtime Comparison
Node.js Runtime
✓Full Node.js APIs
✓crypto, fs, path
✓npm packages
✓Slower cold start
✓export const runtime = "nodejs"
Edge Runtime
△Web Crypto API only
△No fs, no crypto module
△jose, not jsonwebtoken
△Faster cold start (~0ms)
△Default for middleware

03
v15 Breaking Changes

Cookies, Headers & Server Actions

Next.js 15 made cookies() and headers() async. Server Actions replace API routes for internal mutations. Here's the exact migration.

✕ ERRORTypeError: cookies() expects no arguments. In Next.js 15, cookies() is now async and must be awaited.
BROKEN
// ❌ Next.js 15: cookies() is now async
import { cookies } from 'next/headers';
export async function GET() {
const store = cookies() // missing await — returns Promise, not store!
const session = store.get('session') // TypeError
}
↓ FIX
app/api/session/route.tsCORRECT
// app/api/session/route.ts
import { cookies } from 'next/headers';
import { NextResponse } from 'next/server';
export async function GET() {
const cookieStore = await cookies() // ✓ await in v15
const session = cookieStore.get('session')?.value
if (!session) return NextResponse.json({ error: 'No session' }, { status: 401 })
return NextResponse.json({ session })
}
export async function POST() {
const cookieStore = await cookies()
cookieStore.set('session', 'abc123', {
httpOnly: true,
secure: process.env.NODE_ENV === 'production',
sameSite: 'lax',
maxAge: 60 * 60 * 24 * 7, // 7 days
})
return NextResponse.json({ ok: true })
}

Next.js 15 made cookies() asynchronous to align with React's async component model. Always await cookies() before calling .get(), .set(), or .delete(). TypeScript will catch this if you have strict mode enabled.

#cookies#next15#async#breaking-change
Server Action vs Route Handler
Use Server Action when…
▸Calling from React components only
▸Form submissions + mutations
▸Need type safety end-to-end
▸Want to revalidatePath/revalidateTag
▸Internal app operations
Use Route Handler when…
▸External clients call your API
▸Need custom HTTP status codes
▸Streaming responses
▸CORS required for third parties
▸Webhooks from external services

04
Production Patterns

Advanced Patterns

CORS, webhook verification, ISR revalidation, and parallel routes — the patterns that separate production apps from demos.

✕ ERRORAccess to fetch at 'https://api.example.com' from origin 'https://app.example.com' has been blocked by CORS policy: No 'Access-Control-Allow-Origin' header.
BROKEN
// app/api/data/route.ts ❌ — no CORS headers
export async function GET() {
return Response.json({ data: [] })
// External clients get CORS blocked — API Routes are same-origin only
}
↓ FIX
app/api/data/route.tsCORRECT
// app/api/data/route.ts — CORS-enabled route
const ALLOWED_ORIGINS = ['https://app.example.com', 'https://admin.example.com']
function corsHeaders(origin: string | null) {
const allowed = origin && ALLOWED_ORIGINS.includes(origin) ? origin : ALLOWED_ORIGINS[0]
return {
'Access-Control-Allow-Origin': allowed,
'Access-Control-Allow-Methods': 'GET, POST, PUT, DELETE, OPTIONS',
'Access-Control-Allow-Headers': 'Content-Type, Authorization',
'Access-Control-Max-Age': '86400',
}
}
export async function OPTIONS(request: Request) {
const origin = request.headers.get('origin')
return new Response(null, { status: 204, headers: corsHeaders(origin) })
}
export async function GET(request: Request) {
const origin = request.headers.get('origin')
return Response.json({ data: [] }, { headers: corsHeaders(origin) })
}

Export an OPTIONS handler for preflight requests, and include the same CORS headers in all other method responses. For app-wide CORS, handle it in middleware.ts instead of per-route.

#CORS#OPTIONS#headers#cross-origin
Quick Lookup — Common Error Codes
NEXT_NOT_FOUND
Call notFound() from next/navigation
NEXT_REDIRECT
Call redirect() from next/navigation
DYNAMIC_SERVER_USAGE
Add dynamic = "force-dynamic" export
MISSING_DEFAULT_EXPORT
Add default export to page.tsx
EDGE_RUNTIME_INCOMPATIBLE
Remove Node.js APIs, use jose/web-crypto
ASYNC_CLIENT_COMPONENT
Move async logic to Server Component

05
Value Unlocked

Get the Full API Kit

You've seen 4 sections. The full kit has everything — every pattern, every error code, every migration path. Trusted by 847 engineers at companies including Vercel partners and Fortune 500 teams.

Includes
  • ✓All 1,247 API patterns as searchable JSON
  • ✓TypeScript types for every Next.js export
  • ✓Error code → fix lookup table (PDF + JSON)
  • ✓Migration guide: Pages Router → App Router
  • ✓Middleware composition templates
  • ✓Edge runtime compatibility matrix
  • ✓VS Code snippet pack (.code-snippets)
  • ✓Monthly updates as Next.js ships
Recent signups
Marcus J.Staff Eng @ Shopify
2 min ago
Priya K.Tech Lead @ Stripe
14 min ago
Daniel O.Solo founder
1 hr ago

No spam. Unsubscribe anytime. Used by 847+ engineers.