Going DeeperPro· 45 min read

Middleware

Middleware is code that runs before a request reaches a page — perfect for redirecting visitors, blocking the unlogged-in, and rewriting URLs.

What you will learn

  • Explain what middleware runs and when
  • Write a middleware.js that redirects a request
  • Limit middleware to certain routes with a matcher

A checkpoint before every page

Middleware is a function that runs on the server before a request reaches your page or route handler. Think of it as a security guard at the door of your app: every visitor passes the guard first, and the guard can wave them through, send them somewhere else, or quietly redirect them — all before the page even starts rendering.

Common jobs for middleware: send logged-out users to the login page, redirect an old URL to a new one, detect a visitor country or language, or add a header to every request.

The middleware.js file

You write one file named middleware.js in the root of your project (next to the app folder, not inside it). Next.js runs its middleware function for matching requests automatically. It receives the incoming request and can return a response — for example, a redirect.

Middleware redirects logged-out visitors to /login
// middleware.js  (project root)
import { NextResponse } from 'next/server';

export function middleware(request) {
  // pretend we check a login cookie
  const isLoggedIn = request.cookies.get('session');

  if (!isLoggedIn) {
    // send them to the login page instead
    return NextResponse.redirect(new URL('/login', request.url));
  }

  // logged in -> let the request continue as normal
  return NextResponse.next();
}

Note: Output (behaviour): - A visitor WITHOUT a session cookie -> instantly redirected to /login (the page they asked for never even renders). - A visitor WITH a session cookie -> NextResponse.next() lets them through to the page they wanted. The check happened once, at the door, for the whole app.

Limiting middleware to certain routes with a matcher

By default middleware runs on every request, which is wasteful if you only want to guard, say, the dashboard. Export a config object with a matcher to say exactly which paths it should run on.

A matcher limits middleware to the dashboard and account areas
// middleware.js
export const config = {
  matcher: ['/dashboard/:path*', '/account/:path*'],
};

Note: Output (behaviour): Now the middleware runs ONLY for URLs under /dashboard and /account. Public pages like /, /about and /login skip it entirely — faster, and you cannot accidentally lock people out of the login page.

The request journey with middleware, step by step

Here is exactly what happens when a logged-out visitor tries to open /dashboard:

  1. The visitor requests /dashboard. Before anything renders, the request hits middleware.js.
  2. The matcher says this path is covered, so Next.js runs the middleware function.
  3. The function checks for a session cookie with request.cookies.get('session'). There is none.
  4. It returns NextResponse.redirect(new URL('/login', request.url)) — a redirect response.
  5. The browser is sent to /login. The dashboard page never rendered, so no protected content leaked.
  6. Later, after the user logs in (and gets a session cookie), the same request reaches NextResponse.next() and passes through to the dashboard.
Return valueWhat it does
NextResponse.next()Let the request continue to the page
NextResponse.redirect(url)Send the visitor to a different URL
NextResponse.rewrite(url)Show a different page while keeping the URL

Tip: Middleware runs on the lightweight Edge runtime, very early and very fast. Keep it small — checks, redirects and rewrites. Heavy work (database queries, big logic) belongs in your pages, Route Handlers and Server Actions, not in middleware.

Watch out: Middleware is a coarse first gate, not your only defence. It is great for redirecting logged-out users, but always re-check permissions where the real data is read (the page or action). A determined user must not be able to reach protected data just because a redirect was skipped.

Q. What is the right job for Next.js middleware?

Answer: Middleware runs on the server before the request reaches your page. It is ideal for redirects (e.g. send logged-out users to /login), rewrites and request gating — kept small and fast.

✍️ Practice

  1. Write a middleware.js that redirects every request from /old to /new.
  2. Add a matcher so your middleware only runs under /dashboard.

🏠 Homework

  1. Build middleware that redirects visitors without a "session" cookie to /login, limited by a matcher to the /dashboard area.
Want to learn this with a mentor?

CodingClave runs guided, project-based training (28-day, 45-day & 6-month batches).

Explore Training →