A Beginner's Guide to Middleware in Next.js

author
By Tanu Chahal

15/12/2024

cover image for the blog

Understanding Middleware in Next.js

Next.js is a popular React framework that simplifies building modern web applications. One of its powerful features is Middleware, which allows you to execute custom logic before a request is completed. Let’s break down what Middleware is, how it works, and the practical use cases it can solve.


What is Middleware in Next.js?

Middleware in Next.js allows you to intercept incoming requests and execute custom logic before routing occurs. Think of it like a security checkpoint for your web app — you can decide what happens to each request.


Common Use Cases:

  • Redirect users who are not logged in
  • Modify headers for security
  • Rewrite URLs dynamically for SEO
  • Handle requests based on location or device

Example:

import { NextResponse } from 'next/server';

export function middleware(request) { const url = request.nextUrl.clone(); if (!url.pathname.startsWith('/dashboard')) { return NextResponse.redirect(new URL('/login', request.url)); } return NextResponse.next(); }

This example redirects users to the login page if they try to access routes outside of /dashboard.


How Middleware Works

Middleware runs before the request reaches the actual route. It is deployed at the edge (close to the user), enabling fast operations like redirects and rewrites with minimal delay.


Middleware Flow:

  1. Client sends a request
  2. Middleware intercepts and applies logic (e.g., redirect, rewrite, headers)
  3. Edge network or static content is served
  4. Middleware response time is usually 10–50ms, making it ideal for fast request handling.

Adding Middleware to Specific Routes

You don’t need middleware for every route. You can scope middleware using the matcher option in next.config.js.

Example: module.exports = { experimental: { middleware: { matcher: ['/dashboard/:path*'], // Runs only on dashboard routes }, }, };

This improves performance by running middleware only where needed.


Use Cases of Middleware

  1. Handling Custom Headers: You can dynamically modify request/response headers. export function middleware(request) { const response = NextResponse.next(); response.headers.set('X-Custom-Header', 'MyValue'); return response; } Use cases:
  • Add security headers
  • Add analytics tracking

  1. Dynamic URL Rewrites: You can rewrite URLs on the fly without changing client-side routes. export function middleware(request) { const url = request.nextUrl.clone(); if (url.pathname === '/old-route') { url.pathname = '/new-route'; return NextResponse.rewrite(url); } return NextResponse.next(); }

Use cases:

  • SEO-friendly URLs
  • Managing legacy routes

  1. Combining Middleware with Edge Functions Since middleware runs at the edge, it’s ideal for real-time personalization based on location or device. export async function middleware(request) { const geo = request.geo; // Geolocation data console.log(Request from ${geo.city}, ${geo.country}); return NextResponse.next(); }

Use cases:

  • Show location-based content
  • Device-aware experiences

Benefits of Using Middleware

  • Performance: Executes close to users, reducing latency
  • Customization: Apply logic per route or user
  • SEO-Friendly: Rewrite routes for better search indexing
  • Security: Add headers, auth checks, log requests
  • Real-Time Handling: Personalize based on context

Conclusion

Middleware in Next.js is a powerful tool for:

  • Custom logic before routing
  • Dynamic rewrites and redirection
  • Header management and route-level security

Whether you're improving security, optimizing for performance, or personalizing content, Middleware gives you the control you need — fast, flexible, and simple. Give it a try in your next Next.js project!