Optimizing Security & Performance with Middlewares in Next.js

Next.js Middlewares are a powerful but often overlooked feature that can significantly enhance security and optimize performance. They allow you to intercept requests before they reach a page or API, making them perfect for authentication, bot protection, caching, and more.

In this post, we'll dive deep into how to use Middlewares effectively to secure your app and make it faster. ๐Ÿš€

What is Middleware in Next.js?

Middleware is a function that runs before a request is processed. It helps in:

  • Blocking unauthorized access

  • Preventing spam & abuse

  • Improving response times with caching

  • Redirecting users dynamically

    Basic Middleware Example

Create a middleware.ts (or .js) file in your project:

import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";

export function middleware(req: NextRequest) {
  console.log("Middleware triggered for:", req.nextUrl.pathname);
  return NextResponse.next(); // Continue to the requested page
}

This executes on every request unless you configure it otherwise.

๐Ÿ” 1. Enhancing Security with Middleware

๐Ÿ”‘ Protecting Admin Routes

Prevent unauthorized users from accessing sensitive pages:

export function middleware(req: NextRequest) {
  const isLoggedIn = req.cookies.get("auth_token");

  if (!isLoggedIn && req.nextUrl.pathname.startsWith("/admin")) {
    return NextResponse.redirect(new URL("/login", req.url));
  }

  return NextResponse.next();
}

๐ŸŽ Edge Caching for Faster Responses

Reduce server load by caching responses:

export function middleware(req: NextRequest) {
  const res = NextResponse.next();
  res.headers.set("Cache-Control", "public, max-age=3600");
  return res;
}

๐Ÿ”„ 2. Rate Limiting with Middleware

To prevent abuse, limit how often a user can request an API:

const rateLimit = new Map(); // Store request timestamps

export function middleware(req: NextRequest) {
  const ip = req.ip || "unknown";
  const now = Date.now();

  if (rateLimit.has(ip) && now - rateLimit.get(ip)! < 5000) {
    return new Response("Too many requests", { status: 429 });
  }

  rateLimit.set(ip, now);
  return NextResponse.next();
}

Conclusion

By leveraging Middlewares in Next.js, you can enhance security, optimize performance, and improve scalabilityโ€”all while keeping your app efficient and responsive. Implementing them wisely ensures a faster, safer, and more resilient application for both users and developers.