How to Use Middleware in Nextjs

Introduction Middleware in Next.js is a powerful feature that enables developers to run code before a request is completed, allowing for enhanced control over routing, authentication, localization, and more. As modern web applications demand real-time data handling and dynamic user experiences, middleware plays a crucial role in shaping the behavior of Next.js applications at the edge. This tutori

Nov 17, 2025 - 11:35
Nov 17, 2025 - 11:35
 4

Introduction

Middleware in Next.js is a powerful feature that enables developers to run code before a request is completed, allowing for enhanced control over routing, authentication, localization, and more. As modern web applications demand real-time data handling and dynamic user experiences, middleware plays a crucial role in shaping the behavior of Next.js applications at the edge.

This tutorial provides a comprehensive guide on how to use middleware in Next.js, covering practical steps, best practices, useful tools, real-world examples, and answers to common questions. Whether you are new to Next.js or looking to deepen your understanding of middleware, this article will help you master this essential concept for building scalable and efficient web applications.

Step-by-Step Guide

Understanding Middleware in Next.js

Middleware in Next.js runs before a request is processed and can modify the response or redirect users based on custom logic. Unlike traditional API routes or server-side functions, middleware executes at the edge, closer to the user, reducing latency and improving performance.

Step 1: Setting Up a Next.js Project

If you haven't already set up a Next.js project, start by creating one:

Command:

npx create-next-app@latest my-next-middleware-app

Navigate to your project directory:

cd my-next-middleware-app

Step 2: Creating the Middleware File

In Next.js, middleware is defined in a special file named middleware.js or middleware.ts placed at the root of the project or inside the src directory.

Create middleware.js in the root directory.

Step 3: Writing Basic Middleware

The middleware function receives a request object and returns a response or a modified request. Here is a simple example that logs requests:

import { NextResponse } from 'next/server';

export function middleware(request) {

    console.log('Middleware triggered for:', request.nextUrl.pathname);

    return NextResponse.next();

}

This middleware logs the path of each incoming request and then continues processing the request.

Step 4: Conditional Redirects

Middleware can redirect users based on conditions such as authentication or locale.

Example: Redirect unauthenticated users to the login page.

export function middleware(request) {

    const { pathname } = request.nextUrl;

    const isLoggedIn = request.cookies.get('token');

    if (!isLoggedIn && pathname !== '/login') {

        const loginUrl = new URL('/login', request.url);

        return NextResponse.redirect(loginUrl);

    }

    return NextResponse.next();

}

Step 5: Using Middleware for Localization

Middleware can detect the user's preferred language and redirect accordingly:

export function middleware(request) {

    const { pathname, searchParams } = request.nextUrl;

    if (pathname.startsWith('/en') || pathname.startsWith('/fr')) {

        return NextResponse.next();

    }

    const acceptLanguage = request.headers.get('accept-language');

    const preferredLang = acceptLanguage?.startsWith('fr') ? 'fr' : 'en';

    const url = new URL(/${preferredLang}${pathname}, request.url);

    return NextResponse.redirect(url);

}

Step 6: Configuring Middleware Matcher

By default, middleware runs on all routes. You can restrict it using the matcher property in middleware.js:

export const config = {

    matcher: ['/dashboard/:path*', '/profile/:path*'],

};

This example limits middleware execution to URLs starting with /dashboard and /profile.

Step 7: Testing Middleware

Start your Next.js development server:

npm run dev

Open your browser and navigate to different URLs to observe middleware behavior such as redirects and console outputs.

Best Practices

Keep Middleware Lightweight

Middleware runs on every matched request, so ensure it executes quickly to avoid slowing down your app. Avoid heavy computations or large data fetching inside middleware.

Limit Middleware Scope

Use the matcher config to limit middleware to the routes that truly need it. This optimizes performance and reduces unintended side effects.

Secure Sensitive Data

Do not expose sensitive information in middleware. Use secure methods such as HTTP-only cookies to handle authentication tokens.

Use Middleware for Edge-Friendly Tasks

Middleware runs at the edge, making it ideal for tasks like authentication, redirects, and header management rather than complex business logic.

Handle Errors Gracefully

Implement error handling within middleware to avoid crashing your app. Provide fallback responses or redirects when necessary.

Tools and Resources

Next.js Official Documentation

The primary resource for learning about middleware is the Next.js Middleware Documentation. It offers detailed explanations, API references, and examples.

Vercel Edge Network

Next.js middleware runs on Vercels Edge Network by default, leveraging edge computing for optimal performance. Learn more at Vercel Edge Network.

Community Examples and Tutorials

Explore GitHub repositories and tutorials that showcase middleware use cases. Sites like Next.js Examples provide practical implementations.

Middleware Debugging Tools

Use browser dev tools and server logs for debugging middleware behavior. Tools like Postman or curl help simulate requests and test middleware responses.

Real Examples

Example 1: Authentication Middleware

This middleware checks for a session cookie and redirects unauthenticated users:

import { NextResponse } from 'next/server';

export function middleware(request) {

    const token = request.cookies.get('sessionToken');

    if (!token && request.nextUrl.pathname !== '/login') {

        return NextResponse.redirect(new URL('/login', request.url));

    }

    return NextResponse.next();

}

Example 2: Locale Detection Middleware

This middleware detects the preferred language from headers and redirects users accordingly:

export function middleware(request) {

    const url = request.nextUrl.clone();

    if (!url.pathname.startsWith('/en') && !url.pathname.startsWith('/es')) {

        const lang = request.headers.get('accept-language')?.split(',')[0].startsWith('es') ? 'es' : 'en';

        url.pathname = /${lang}${url.pathname};

        return NextResponse.redirect(url);

    }

    return NextResponse.next();

}

Example 3: Custom Header Injection

Middleware can add custom headers to responses for security or tracking:

export function middleware(request) {

    const response = NextResponse.next();

    response.headers.set('X-Custom-Header', 'MyHeaderValue');

    return response;

}

FAQs

What is the difference between Next.js middleware and API routes?

Middleware intercepts requests before they reach API routes or pages and can modify or redirect them. API routes handle business logic and data responses, while middleware is for routing, authentication, and edge-related tasks.

Where should I place the middleware file in a Next.js project?

Place middleware.js or middleware.ts at the root of your project or inside the src directory.

Can middleware access request cookies?

Yes, middleware can read cookies from the request using request.cookies.get('cookieName').

Does middleware affect client-side navigation?

Middleware runs only on server-side requests, including initial page loads and API calls, but not during client-side navigation using Next.jss built-in router.

Is middleware compatible with static site generation (SSG)?

Yes, middleware can run before serving static pages, enabling dynamic behaviors such as redirects or authentication checks even on statically generated pages.

Conclusion

Middleware in Next.js offers a versatile and efficient way to control request flows, enforce security, manage localization, and customize responses at the edge. By following the step-by-step guide and best practices outlined here, developers can leverage middleware to build faster, more secure, and user-friendly applications.

Understanding how to implement and optimize middleware will empower you to enhance your Next.js projects and deliver better experiences to your users. Experiment with the examples provided, explore official resources, and integrate middleware thoughtfully to unlock its full potential.