Next.js Middleware for All Routes: A Comprehensive Guide

Middleware in Next.js is a robust feature that acts as a bridge between the requests and their response objects. It allows us to easily intercept incoming requests and perform intended operations before they reach their target routes. This feature is important when we want to implement any operations or check all routes in our application…

By.

•

min read

Middleware in Next.js is a robust feature that acts as a bridge between the requests and their response objects. It allows us to easily intercept incoming requests and perform intended operations before they reach their target routes.

This feature is important when we want to implement any operations or check all routes in our application for example authentication, data parsing,  logging etc. In this article, we will discuss the concept of Next.js middleware for all routes in detail with examples.

 

What is Middleware in Next.js?

In Next.js, middleware is a function which can access and intercept the incoming request and also the outgoing response in our application. It helps to work with HTTP requests and their responses which reside between the requests and the final target routes. Middleware is used in various use cases like:

  • Logging
  • Authentication
  • Body parsing
  • Error handling

Middleware in the Next js app, is executed on the server side before a request is processed by the application on the page. It can be applied to every page or on a single page as well. Let’s have a look at a basic example of a Next.js middleware:

//loggingMiddleware.js

import { NextApiRequest, NextApiResponse } from 'next'

const loggingMiddleware = (req: NextApiRequest, res: NextApiResponse, next: Function) => {
  console.log(`${req.method} ${req.url}`);
  next();
}

export default loggingMiddleware;

In the above example, the loggingMiddleware function logs the method and URL of each incoming request. The next function is called to pass control to the next middleware function. Suppose if there are no other middleware functions, the request will be processed.

 

How to Setup Middleware for All Routes

In a Next.js application, we can easily implement middleware to all routes. So that the middleware function will run for every incoming request for all the routes being accessed.  Here’s a step-by-step guide on how to do this:

 

Step 1: Create a Middleware Function

First, you need to create a middleware function. This function should accept three arguments including req (the request object), res (the response object), and next (a function to call when your middleware is done).

Here’s an example of a simple logging middleware function:

// middleware/loggingMiddleware.js

import { NextApiRequest, NextApiResponse } from 'next'

const loggingMiddleware = (req: NextApiRequest, res: NextApiResponse, next: Function) => {
  console.log(`Incoming request: ${req.method} ${req.url}`);
  next();
}

export default loggingMiddleware;

In the above example, the loggingMiddleware function logs the method and URL of each incoming request. The next function is called to pass control to the next middleware function. If there is no other middleware, the request will be processed.

 

Step 2: Apply the Middleware to All Routes

Next, you need to apply your middleware function to all routes. In Next.js, this can be done by using the middleware function in the _app.js file, which is the top-level component in Next.js.

Here’s how to apply the loggingMiddleware function to all routes:

// pages/_app.js

import loggingMiddleware from '../middleware/loggingMiddleware'

function MyApp({ Component, pageProps }) {
  loggingMiddleware(req, res, () => {})
  return <Component {...pageProps} />
}

export default MyApp

 

In this example, the loggingMiddleware function is imported from the middleware directory and used in the MyApp component. The loggingMiddleware function will run for every request to any route in the application.

 

Step 3: Test Your Middleware

Finally, you should test your middleware to ensure it’s working correctly. You can do this by running your Next.js application and making requests to various routes. You should see the log messages from your loggingMiddleware function in your server console.

 

Advanced Concepts in Next.js Middleware

The basic implementation of Next.js middleware for all routes can handle almost all common use cases, but there are also advanced concepts and features in Next.js middleware that we will discuss further.

 

Middleware Flags in Next.js

Next.js middleware supports several flags that can be used to control the behaviour of the middleware. These flags are properties of the req and res objects which the middleware function receives.

These are some of the most important flags:

  • req.method: Contains the HTTP method of the request (e.g., GET, POST, etc.).
  • req.url: Contains the URL of the request.
  • res.statusCode: Can be used to set the HTTP status code of the response.
  • res.setHeader(name, value): This method can be used to set a response header.

Example of a middleware function with flags:

// middleware/advancedMiddleware.js

import { NextApiRequest, NextApiResponse } from 'next'

const advancedMiddleware = (req: NextApiRequest, res: NextApiResponse, next: Function) => {
  if (req.method !== 'GET') {
    res.statusCode = 405;
    res.setHeader('Allow', 'GET');
    res.end('Method not allowed');
    return;
  }

  console.log(`Incoming request: ${req.method} ${req.url}`);
  next();
}

export default advancedMiddleware;

The advancedMiddleware function checks if the request method is GET. If it’s not GET, it sets the response status code to 405 means Method Not Allowed. Also sets the Allow header to GET, and ends the response with a message.

 

Handling Advanced Use Cases with Middleware

Next.js middleware can be used to handle advanced use cases such as authentication, error handling etc. For example, you can create a middleware function to check if a user is authenticated before they can access certain routes. In such cases, we can use Middleware as Route or Path guards in the Nextjs app. If they are not authenticated, will be redirected to a login page.

Example of an authentication middleware function:

// middleware/authMiddleware.js

import { NextApiRequest, NextApiResponse } from 'next'

// Mock function to check if the user is authenticated
const isAuthenticated = (authHeader) => {
  // Replace this with your actual authentication logic
  return authHeader === "Bearer valid_token";
}

const authMiddleware = (req: NextApiRequest, res: NextApiResponse, next: Function) => {
  const authHeader = req.headers.authorization;

  if (!authHeader || !isAuthenticated(authHeader)) {
    res.writeHead(302, { Location: '/login' });
    res.end();
    return;
  }

  next();
}

export default authMiddleware;

The authMiddleware function checks if the Authorization header is present in the request. If it’s not, it sets the response status code to 401 (Unauthorized) and finishes the response with a message. If the Authorization header is present, it checks if the user is authenticated and redirects them to the login page if they are not authorized.

Understanding and using these advanced concepts in Next.js middleware for all routes can help you create more robust and secure Next.js applications.

Hope this will be helpful.

Leave a Reply

Your email address will not be published. Required fields are marked *