Next.js Middleware: A Developer’s Guide with Real Use Cases and Code Examples

Next.js Middleware: A Developer’s Guide with Real Use Cases and Code Examples

Author: Abdulkader Safi

Position: Software Engineer

Next.js has become the go-to React framework for building production-grade web applications. With features like file-based routing, API routes, and server-side rendering, it offers developers speed and flexibility. But one feature often underutilized (or misunderstood) is Next.js Middleware.

Middleware enables powerful edge logic that executes before a request is completed—allowing developers to intercept, modify, or redirect requests in near real-time. In this article, we’ll explore what Next.js Middleware is, when to use it, and walk through concrete code examples and real-world use cases.


What is Next.js Middleware?

Middleware in Next.js is a function that runs before a request is processed by your app’s routes or APIs. It lives at the edge layer, meaning closer to the user, reducing latency and allowing for smarter request handling.

Key characteristics:

  • Runs on the Edge Runtime (based on V8, not Node.js).
  • Executes before rendering or API logic.
  • Can rewrite, redirect, modify headers, or return responses.
  • Runs in a stateless, lightweight environment, making it blazing fast.

File location:

/middleware.ts  # or middleware.js

Example boilerplate:

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

export function middleware(request: NextRequest) {
  // Example: Block access to /admin if not logged in
  if (
    !request.cookies.get("auth-token") &&
    request.nextUrl.pathname.startsWith("/admin")
  ) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  return NextResponse.next();
}

Why Use Middleware?

Think of Middleware as your bouncer at the door—it decides what happens before the request enters your app. Some common scenarios:

  1. Authentication & Authorization
    • Protect private routes.
    • Redirect unauthenticated users to login.
  2. A/B Testing & Personalization
    • Show different experiences to users based on cookies, headers, or geolocation.
  3. Localization
    • Detect user’s region or language and redirect accordingly.
  4. Bot Detection & Rate Limiting
    • Block suspicious requests early.
  5. Analytics & Logging
    • Capture request metadata without touching route logic.

Practical Use Cases with Code

1. Protecting Routes with Authentication

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

export function middleware(request: NextRequest) {
  const token = request.cookies.get("token");

  if (!token && request.nextUrl.pathname.startsWith("/dashboard")) {
    return NextResponse.redirect(new URL("/login", request.url));
  }

  return NextResponse.next();
}

👉 Useful for dashboards, admin panels, or member-only content.

2. Internationalization (i18n) Redirects

export function middleware(request: NextRequest) {
  const { pathname } = request.nextUrl;
  const locale = request.headers.get("accept-language")?.split(",")[0] || "en";

  if (pathname === "/") {
    return NextResponse.redirect(new URL(`/${locale}`, request.url));
  }
}

👉 Detects browser language and redirects to localized content (/en, /fr, etc.).

3. A/B Testing or Feature Flags

export function middleware(request: NextRequest) {
  const group = Math.random() < 0.5 ? "A" : "B";

  if (group === "A") {
    return NextResponse.rewrite(new URL("/experiment/a", request.url));
  }

  return NextResponse.rewrite(new URL("/experiment/b", request.url));
}

👉 Split traffic dynamically at the edge without complex setup.

4. Blocking Bots and Bad Actors

const blockedAgents = ["curl", "python", "scrapy"];

export function middleware(request: NextRequest) {
  const ua = request.headers.get("user-agent")?.toLowerCase() || "";

  if (blockedAgents.some((agent) => ua.includes(agent))) {
    return new Response("Blocked", { status: 403 });
  }

  return NextResponse.next();
}

👉 Prevent scrapers or unwanted crawlers from hammering your app.


Performance Considerations

  • Runs at the Edge: Middleware is executed globally at CDN-level, so it’s fast.
  • Stateless: No fs, crypto, or Node.js APIs. Use Web APIs only.
  • Bundle Size Matters: Keep middleware lightweight—avoid large dependencies.
  • Chaining Middleware: You can conditionally run multiple checks, but ensure minimal overhead.

Best Practices

  • Place logic only where needed—don’t run heavy computation.
  • Combine middleware with cookies or headers for personalization.
  • Use NextResponse.rewrite for internal rewrites and NextResponse.redirect for external navigation.
  • Always have a fallback path to avoid infinite loops.

SEO Benefits of Middleware

Middleware indirectly helps SEO by:

  • Improving page load speed (early redirects reduce TTFB).
  • Supporting localized content (serving language-specific pages).
  • Enforcing canonical routes (redirect duplicates).
  • Blocking spam/bots, protecting crawl budget.

Conclusion

Next.js Middleware is more than just a request filter—it’s a powerful edge tool that lets developers build secure, performant, and personalized apps without bloating client or server logic.

Whether you’re handling authentication, localization, A/B testing, or bot protection, Middleware should be in your Next.js toolbox.

With great power comes great responsibility: keep your middleware fast, simple, and focused.


✅ Pro Tip: Combine Middleware with Edge API Routes for even more dynamic edge-driven apps.


🤝 Need a Custom RSVP System or Dashboard?

I help businesses build tools that actually work , even on tight deadlines.

Whether you're planning an event, need internal tools, or want a custom dashboard for your team , I can help.

Reach out

📧 Email: safi.abdulkader@gmail.com | 💻 LinkedIn: @abdulkader-safi | 📱 Instagram: @abdulkader.safi | 🏢 DSRPT

Drop me a line, I’m always happy to collaborate! 🚀


© Abdulkader Safi