middleware.js

Runs code before a request completes to rewrite, redirect, or modify headers.

Since Next 12 (Edge); App Router 13+ Spec ↗

Syntax

export function middleware(request) { return NextResponse.next() }

Parameters

NameTypeRequiredDescription
request NextRequest Yes The incoming request with `nextUrl`, `cookies`, `geo` helpers.
config { matcher: string | string[] } No Exported `config.matcher` limits which paths run middleware.

Returns

NextResponse | Response | undefined — next(), redirect, rewrite, or modified response.

Examples

// middleware.ts (project root)
import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'

export function middleware(request: NextRequest) {
  const token = request.cookies.get('token')?.value
  if (!token) {
    return NextResponse.redirect(new URL('/login', request.url))
  }
  return NextResponse.next()
}

export const config = {
  matcher: ['/dashboard/:path*', '/account/:path*'],
}
import { NextResponse } from 'next/server'

export function middleware(req) {
  const res = NextResponse.next()
  res.headers.set('x-app-version', '2.0')
  return res
}

Notes

A single `middleware.ts` lives at the project root (or `src/`). It runs on the Edge runtime by default (in Next 15.x you can opt into the Node.js runtime). Keep it lightweight; use `matcher` to scope it. Cannot return a response body for page routes — use rewrite/ redirect/next.

See also