Understanding Middleware in Next.js – A Beginner’s Guide
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.