Understanding Middleware in Next.js – A Beginner’s Guide

Wayne
Por Wayne ·

Next.js is known for combining the best of React with powerful features for building modern web applications. One of these powerful features is Middleware. If you’ve ever wanted to run code before a request is completed (for example, checking authentication or redirecting users), Middleware is the tool for the job.

What is Middleware?

In simple terms, Middleware is code that runs before a request reaches your page or API route. It allows you to inspect the incoming request and decide what should happen next.

For example, you might:

  • Redirect users who aren’t logged in
  • Rewrite the URL to serve different content
  • Add custom headers to requests or responses
  • Log requests for analytics

👉 Think of Middleware as a “gatekeeper” between the user’s request and your application.

Where Does Middleware Run?

  • Middleware runs on the Edge Runtime, which is faster and closer to the user.
  • This means it doesn’t run in Node.js (no access to Node APIs like fs).
  • It’s ideal for things like authentication, redirects, and personalization.

Creating Middleware

In Next.js, you create a file called middleware.js (or middleware.ts) in the root of your project.

Example: Simple Logger

// middleware.js
import { NextResponse } from "next/server";

export function middleware(request) {
  console.log("Middleware running for:", request.url);
  return NextResponse.next(); // allow request to continue
}

Here’s what happens:

  • A request comes in.
  • The middleware runs.
  • If you return NextResponse.next(), the request proceeds as normal.

Redirecting with Middleware

You can easily redirect users. For example, redirecting unauthenticated users to /login:

// middleware.js
import { NextResponse } from "next/server";

export function middleware(request) {
  const isLoggedIn = false; // Example check (replace with real logic)

  if (!isLoggedIn) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  return NextResponse.next();
}

Rewriting with Middleware

Instead of redirecting, you can “rewrite” the request so users see a different page while the URL stays the same:

// middleware.js
import { NextResponse } from "next/server";

export function middleware(request) {
  const url = request.nextUrl;

  if (url.pathname === "/old-page") {
    return NextResponse.rewrite(new URL("/new-page", request.url));
  }

  return NextResponse.next();
}

👉 This is great for handling legacy routes or A/B testing.

Matching Routes

By default, Middleware runs for every request. You can control this using a matcher config.

// middleware.js
export const config = {
  matcher: ["/dashboard/:path*", "/profile/:path*"],
};

Now Middleware only runs for /dashboard/* and /profile/*.

Key Points to Remember

  • Middleware runs before the request reaches your pages or API routes.
  • Runs on the Edge Runtime (no Node.js APIs).
  • Common use cases:
  • Authentication & authorization
  • Redirects & rewrites
  • Logging & analytics
  • Localization (e.g., redirect users based on country)
  • Use NextResponse.next() to continue, NextResponse.redirect() to redirect, and NextResponse.rewrite() to change the destination.