Introduction

Middleware in Next.js allows you to run code before a request is completed, which can be useful for tasks like authentication, logging, or redirects. Next.js introduced middleware support starting from version 12, enabling you to create and use custom middleware for your application.

Understanding Next.js Middleware

Middleware functions run before a request is completed, allowing you to.

Setting Up Middleware

Create a Middleware File

Create a _middleware.js file inside the pages directory or any specific subdirectory where you want the middleware to apply. Middleware in Next.js can be applied globally or to specific routes.

Example. Global Middleware.

// pages/_middleware.js
import { NextResponse } from 'next/server';
export function middleware(request) {
  const { pathname } = request.nextUrl; 
  // Redirect example
  if (pathname === '/old-page') {
    return NextResponse.redirect(new URL('/new-page', request.url));
  }  
  // Add custom logic here
  return NextResponse.next();
}

Example. Route-Specific Middleware.

Place the middleware file in the specific directory you want it to apply to.

// pages/api/_middleware.js
import { NextResponse } from 'next/server';
export function middleware(request) {
  // Middleware logic for API routes
  return NextResponse.next();
}

Use Middleware for Authentication

Create middleware to protect certain pages by checking user authentication status.

// pages/_middleware.js
import { NextResponse } from 'next/server';
import { getToken } from 'next-auth/jwt';
export async function middleware(request) {
  const token = await getToken({ req: request });
  if (!token && request.nextUrl.pathname !== '/login') {
    return NextResponse.redirect(new URL('/login', request.url));
  }
  return NextResponse.next();
}

Testing Middleware

Run your Development Server

Ensure middleware logic is correctly applied by running your development server.

npm run dev

Test Functionality

Test different routes and scenarios to verify that middleware behaves as expected.

Advanced Middleware Techniques

Dynamic Middleware

You can create dynamic middleware to handle different environments or conditions.

// pages/_middleware.js
import { NextResponse } from 'next/server';
export function middleware(request) {
  const isDev = process.env.NODE_ENV === 'development';
  if (isDev) {
    console.log('Development mode');
  }
  return NextResponse.next();
}

Custom Response Headers

Add custom headers to responses.

// pages/_middleware.js
import { NextResponse } from 'next/server';

export function middleware(request) {
  const response = NextResponse.next();
  response.headers.set('X-Custom-Header', 'MyHeaderValue');
  return response;
}

Best Practices

Summary

Custom middleware in Next.js provides a powerful way to intercept and modify requests. By following this guide, you can create middleware to handle various tasks such as authentication, redirection, and response customization. Test your middleware thoroughly and adhere to best practices for a secure and efficient implementation.