Handling Middleware in Next.js

Introduction

Middleware in Next.js lets you run code before a request is processed. It's useful for checking if a user is logged in, logging requests, changing URLs, or modifying response headers. Introduced in Next.js 12, middleware runs on the Edge Network for fast execution.

In this article, we'll cover the basics of using middleware in Next.js, including how to create, set up, and use it in your app.

What is Middleware?

Middleware functions are bits of code that run before a request is completed. In Next.js, middleware can.

  • Check if a user is authenticated.
  • Log details about the request.
  • Rewrite or redirect URLs.
  • Modify response headers.

Middleware in Next.js is defined in a file named _middleware.js or _middleware.ts (for TypeScript projects) and can be placed in any folder under the pages directory. The middleware applies to all routes in that folder and its subfolders.

Creating Middleware

To create middleware in Next.js, follow these steps.

Create a Middleware File

Create a file named _middleware.js or _middleware.ts in the desired folder under the pages directory.

Export a Middleware Function

The middleware function should be an async function that receives a Request object and a NextResponse object.

// pages/_middleware.js
import { NextResponse } from 'next/server';
export async function middleware(req) {
  // Middleware logic here
  return NextResponse.next();
}

Middleware example authentication check

Here's how you can create middleware that checks if a user is authenticated. If the user is not authenticated, they will be redirected to the login page.

// pages/_middleware.js
import { NextResponse } from 'next/server';
export async function middleware(req) {
  const { pathname } = req.nextUrl;
  // Check if the user is authenticated
  const isAuthenticated = req.cookies.get('auth_token');
  // If user is not authenticated and trying to access a protected route
  if (!isAuthenticated && pathname !== '/login') {
    return NextResponse.redirect('/login');
  }
  // Allow the request to proceed
  return NextResponse.next();
}

In this example.

  • We check if the request has an auth_token cookie.
  • If the user is not authenticated and tries to access a route other than /login, they are redirected to the /login page.
  • Authenticated requests and requests to /login are allowed to proceed.

Middleware example logging requests

Here's how to create middleware that logs request details like the URL and method.

// pages/_middleware.js
export async function middleware(req) {
  console.log(`Request URL: ${req.nextUrl.href}`);
  console.log(`Request Method: ${req.method}`);  
  return NextResponse.next();
}

In this example.

  • We log the URL and method of each incoming request.
  • The request is then allowed to proceed using NextResponse.next().

Middleware example URL rewrites

You can also use middleware to rewrite URLs before they reach the route handler. This can be useful for implementing clean URLs or vanity URLs.

// pages/_middleware.js
import { NextResponse } from 'next/server';
export async function middleware(req) {
  const { pathname } = req.nextUrl;
  // Rewrite /about to /about-us
  if (pathname === '/about') {
    return NextResponse.rewrite(new URL('/about-us', req.url));
  }
  return NextResponse.next();
}

In this example.

  • Requests to /about are rewritten to /about-us.
  • Other requests are allowed to proceed without modification.

Middleware Configuration

You can adjust middleware settings using the config object. For example, you can limit middleware to specific paths or exclude certain paths.

// pages/_middleware.js
export async function middleware(req) {
  // Middleware logic here
  return NextResponse.next();
}
export const config = {
  matcher: ['/protected/:path*', '/another-path'],
};

In this configuration.

The middleware only applies to paths matching /protected/* and /another path.

Conclusion

Middleware in Next.js is a powerful tool that lets you handle requests and responses flexibly and efficiently. By learning how to create and configure middleware, you can easily implement features like authentication, logging, and URL rewrites.