homeblog

Mastering Next.js Middleware: Practical Use Cases

Mon Dec 02 2024
Mastering Next.js Middleware: Practical Use Cases

Aymen Jdily

Mastering Next.js Middleware: Practical Use Cases

Mastering Next.js Middleware: Practical Use Cases

Introduction

Middleware is a powerful feature in Next.js that allows you to run code before a request is completed. It enables tasks such as authentication, logging, redirection, and request transformation. In this blog, we'll explore how middleware works, common use cases, and practical examples to enhance your Next.js applications.

1. What is Middleware in Next.js?

Middleware is code that executes during the request lifecycle before reaching the final API route or rendering a page. Introduced in Next.js 12, middleware runs in the Edge Runtime, making it fast and scalable.

Key characteristics:

  • Runs on every request.
  • Executes at the edge, improving latency.
  • Can modify the request or response.

Middleware is defined in the middleware.js file in the project root or any folder within the pages directory.

2. How to Set Up Middleware

Create a middleware.js file in your Next.js project:

1import { NextResponse } from 'next/server';
2
3export function middleware(request) {
4  console.log('Middleware executed');
5  return NextResponse.next();
6}

Place this file at the root or in a folder (e.g., pages/api/middleware.js) to control its scope.

3. Practical Use Cases for Middleware

a) Authentication

Redirect unauthorized users to the login page.

1import { NextResponse } from 'next/server';
2
3export function middleware(request) {
4  const token = request.cookies.get('authToken');
5  
6  if (!token) {
7    return NextResponse.redirect(new URL('/login', request.url));
8  }
9
10  return NextResponse.next();
11}

b) Logging Requests

Log incoming requests for monitoring or debugging.

1export function middleware(request) {
2  console.log(`Request made to: ${request.nextUrl.pathname}`);
3  return NextResponse.next();
4}

c) Redirecting Based on Conditions

Redirect users based on locale, user role, or other factors.

1export function middleware(request) {
2  const { pathname } = request.nextUrl;
3
4  if (pathname.startsWith('/old-path')) {
5    return NextResponse.redirect(new URL('/new-path', request.url));
6  }
7
8  return NextResponse.next();
9}

d) Rate Limiting

Throttle requests to prevent abuse.

1let requestCount = 0;
2
3export function middleware(request) {
4  requestCount += 1;
5
6  if (requestCount > 100) {
7    return new Response('Rate limit exceeded', { status: 429 });
8  }
9
10  return NextResponse.next();
11}

e) A/B Testing

Serve different versions of a page for A/B testing.

1export function middleware(request) {
2  const experimentGroup = Math.random() > 0.5 ? 'A' : 'B';
3
4  return NextResponse.rewrite(
5    new URL(`/experiment-${experimentGroup}`, request.url)
6  );
7}

4. Advanced: Combining Middleware with Edge APIs

Middleware works seamlessly with Edge APIs to handle geolocation or other request-specific data.

Example: Serve region-specific pages:

1export function middleware(request) {
2  const country = request.geo?.country || 'US';
3
4  return NextResponse.rewrite(new URL(`/${country}/home`, request.url));
5}

5. Best Practices

  • Use Conditions Wisely: Avoid overloading middleware with heavy logic.
  • Scope Middleware: Place middleware.js in specific folders to limit its application.
  • Secure Sensitive Data: Never expose secrets or sensitive operations in middleware.
  • Test Thoroughly: Since middleware affects every request, ensure thorough testing.

Conclusion

Middleware in Next.js is a versatile tool for handling requests dynamically and enhancing your application’s functionality. Whether you’re managing user authentication, redirects, or optimizing performance, middleware empowers you to customize the behavior of your application at the edge.

Try implementing these practical use cases in your projects and watch your apps become more efficient and responsive.