LearnAI ToolsCareerPractice BuildsPlayContact
Lesson 3516 min read

Middleware

Run code before a request completes — for redirects, authentication checks, and header rewrites — using middleware.ts.

What Is Middleware?

Middleware runs on every matching request, before it reaches a route's page or Route Handler. It sits between the incoming request and your application code, and can redirect, rewrite, or modify the request or response before your route ever runs.

Request arrives
↓
middleware.ts runs
↓
Continues to the matched route, or redirects/rewrites

Creating Middleware

Middleware lives in a single middleware.ts file at the project root (or inside src/, if you used that option).

// middleware.ts
import { NextResponse } from 'next/server';
export function middleware(request) {
const isLoggedIn = request.cookies.has('session');
if (!isLoggedIn && request.nextUrl.pathname.startsWith('/dashboard')) {
return NextResponse.redirect(new URL('/login', request.url));
}
return NextResponse.next();
}

The matcher Config

By default, middleware runs on every request. Export a config with a matcher to limit it to specific paths, avoiding unnecessary work on routes that don't need it.

export const config = {
matcher: ['/dashboard/:path*', '/account/:path*'],
};
Keep It Lightweight

Middleware runs on the Edge Runtime, a lighter, faster execution environment than a full Node.js server — it does not support every Node.js API, so keep logic focused on things like cookies, headers, and redirects rather than heavy computation or direct database calls.

Common Use Cases

Authentication Gates

Redirect unauthenticated visitors away from protected routes before the page even renders.

Geolocation / A-B Routing

Rewrite requests to a locale-specific or experiment-specific path based on request headers.

Logging & Headers

Attach custom headers or logging metadata to every request passing through.

Rate Limiting Checks

Reject requests early, before they reach more expensive route logic.

Common Beginner Mistakes

Doing full authentication (verifying a database session) inside middleware

Middleware runs on every matched request, on the Edge Runtime — keep it to lightweight checks like the presence of a token, and verify the token's full validity in the actual route.

Forgetting to return NextResponse.next()

Without explicitly returning next() (or a redirect/rewrite), the request may not proceed as expected — always return a response from the middleware function.

FAQs

No — there is exactly one middleware.ts per project, at the root; use the matcher config and conditional logic inside it to handle different sections differently.

By default it can — this is exactly why the matcher config exists, to exclude paths like /_next/static or images that don't need middleware logic.

Summary

Middleware gives you a single, request-level checkpoint for redirects, lightweight auth checks, and header manipulation. With data and actions covered, the next section moves into optimizing assets — starting with images.

Next Lesson →

Image Optimization