Vercel’s Edge Middleware lets you run code at the network edge, close to your users, before a request even hits your application.

Let’s see it in action. Imagine you have a Vercel project and you want to redirect users from an old URL structure to a new one. You can do this with a simple middleware.

// middleware.ts
import { NextResponse } from 'next/server';
import type { NextRequest } from 'next/http';

export function middleware(request: NextRequest) {
  const url = request.nextUrl.clone();

  if (url.pathname === '/old-path') {
    url.pathname = '/new-path';
    return NextResponse.redirect(url);
  }

  return NextResponse.next();
}

This code snippet, placed in your project’s root directory as middleware.ts (or .js), intercepts incoming requests. If the pathname matches /old-path, it rewrites the URL to /new-path and sends a redirect response. Otherwise, it allows the request to proceed normally.

The power here is that this code runs on Vercel’s global Edge Network, not on a server in your data center. This means the redirect happens incredibly fast, with minimal latency, because it’s executed on a server geographically closer to the user making the request.

This pattern is foundational for several advanced use cases:

  • A/B Testing: You can serve different versions of your application based on user characteristics or random chance. Middleware can inspect request headers (like User-Agent or custom headers) or cookies to decide which variant to serve.
  • Authentication & Authorization: Before a request hits your API routes or pages, middleware can verify if the user is logged in or has the necessary permissions. It can check JWTs in headers, session cookies, or even make external API calls to validate credentials. If unauthorized, it can return a 401 or 403 response, or redirect to a login page.
  • Internationalization (i18n): Detect the user’s preferred language from their browser’s Accept-Language header or a cookie, and then rewrite the URL to the appropriate language subdomain or path (e.g., /en/about or fr.example.com/a-propos).
  • Dynamic Routing & Rewrite Rules: Beyond simple redirects, you can dynamically rewrite URLs based on complex logic. For example, you could map a slug from an external CMS to an internal page structure.
  • Bot Detection & Scraping Prevention: Middleware can analyze incoming requests for suspicious patterns indicative of bots or scrapers (e.g., high request rates from a single IP, unusual user agents) and block them early.

The NextResponse object is your primary tool here. You can use NextResponse.next() to continue processing the request, NextResponse.rewrite() to internally change the URL without the user knowing (useful for serving content from a different path), or NextResponse.redirect() to send a client-side redirect. You can also construct custom responses with specific status codes and headers.

The request object (NextRequest) gives you access to the incoming request’s URL, headers, cookies, and even the request body (though processing the body in middleware can impact performance). When you modify the URL, remember to clone() it first, as URLs are immutable.

When you’re dealing with complex routing logic, especially for internationalization, you might find yourself needing to parse and manipulate URL segments extensively. A common, often overlooked, detail is how Vercel’s middleware handles the basePath configuration. If you have a basePath set in your next.config.js (e.g., /app), all paths within your middleware will be relative to that basePath. This means if your middleware is checking for /about, and your basePath is /app, it will only match requests to /app/about. You need to account for this consistently in your path comparisons and rewrites.

The next step is understanding how to integrate external data sources or complex state management within your Edge Middleware.

Want structured learning?

Take the full Vercel course →