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.