Next.js production engineering

Next.js Middleware in Production: Routing, Security & Edge Runtime

Middleware is a request boundary, not a second application server. Keep its scope narrow, make its decisions explicit, and give every redirect or block a reason you can test and observe.

RequestMatchDecideContinue

Match only requests that need a decision

Middleware runs before the route handler or page for the paths it matches, which makes it useful for routing, locale selection, lightweight authorization gates, experiments, and response headers. It also makes an overly broad matcher expensive and risky. Start by naming the small set of route families that need the behavior. Exclude static assets, image optimization paths, health checks, and public endpoints unless there is a concrete reason to include them.

import { NextResponse } from "next/server";

export function middleware(request) {
  const requestHeaders = new Headers(request.headers);
  requestHeaders.set("x-request-id", crypto.randomUUID());
  return NextResponse.next({ request: { headers: requestHeaders } });
}

export const config = {
  matcher: ["/dashboard/:path*", "/settings/:path*"],
};

Write matcher rules as product policy, then test representative URLs. A catch-all expression may look convenient but can accidentally intercept callbacks, assets, or deployment probes. If the objective is a security header for every document response, prefer the platform's header configuration where it is simpler and easier to audit.

Make the middleware decision a clear access boundary

Authentication identifies a requester; authorization decides whether that requester may access a specific resource. Middleware can perform an early redirect when a session is missing, but it should not become the only authorization control. Route handlers and data access still need resource-level checks because requests can arrive through paths or service calls that bypass a browser navigation.

Public routes

Proceed without session checks; keep their matchers out of the protected set.

Protected routes

Validate a trusted session and send an unauthenticated visitor to a deliberate sign-in path.

Sensitive actions

Enforce tenant, role, and capability rules again beside the data or action.

Use a server-verified cookie or token, never a client-provided role flag. Keep return URLs local and validated, and retain the original path only when it is safe to send a user back there. Our Next.js authentication guide covers the session and RBAC design that should sit behind this early gate.

Design for the edge runtime you actually have

Middleware commonly runs in an edge-like runtime with different APIs, cold-start behavior, dependency support, and network constraints from a long-lived Node.js server. Treat it as a fast decision point. Decode and verify only what is necessary, avoid large SDKs and database lookups on every request, and set a small time budget for any unavoidable remote call.

  • Keep dependencies small and compatible with the runtime your host documents.
  • Do not rely on process-local memory for sessions, flags, rate limits, or mutable state.
  • Do not place secrets in rewritten URLs, response headers, logs, or browser-readable cookies.
  • Use a stable request ID to connect middleware decisions with downstream logs.

When a request needs database access or a multi-step policy decision, let middleware route it to a normal server boundary rather than silently turning the edge into an application bottleneck. For safe secret handling across that boundary, see our Next.js environment-variables guide.

Prevent redirect loops and unsafe rewrites

A redirect changes the browser URL; a rewrite serves a different route while preserving it. Both are powerful, and both need guardrails. First decide whether a user, crawler, API client, or internal callback should receive the behavior. Then make the decision idempotent: the destination must not immediately satisfy the same condition and redirect again.

Redirect safety rule: exclude the destination routes from the matcher or detect them explicitly, preserve only approved local return paths, and test expired sessions, malformed cookies, and deep links.

Use permanent redirects only for durable URL moves. Authentication redirects, experiments, locale selection, and maintenance states are temporary and should retain an appropriate status. If middleware adds headers such as CSP or request identifiers, verify that it does not overwrite headers set later in the response pipeline. The staged rollout guidance in our Next.js CSP guide is a useful pattern for sensitive response changes.

Release middleware as a measurable infrastructure change

Because middleware can affect a large portion of traffic, release it with the same care as a gateway rule. Start with a narrow matcher or a non-blocking observation mode. Log a stable decision name, route template, outcome, latency, and release identifier—never the raw token or personal data that informed the decision. Compare the error rate, redirect rate, and latency against a baseline before broadening the rule.

Build route-level tests for public routes, protected routes, callback endpoints, static assets, expired sessions, deep links, and the redirect destination. In staging, test the actual hosting runtime rather than only a local Node.js environment. If a rollout needs targeted exposure, combine it with the controlled cleanup rules in our Next.js feature-flags guide.

Next.js middleware production checklist

✓ Matchers name only the routes that need middleware

✓ Static assets, callbacks, and probes are deliberately excluded

✓ Middleware handles early gates; routes still authorize resources

✓ Edge-compatible dependencies and short time budgets are used

✓ Redirect destinations cannot re-trigger the same redirect

✓ Return URLs are local, validated, and free of sensitive data

✓ Decision logs include safe, stable operational fields

✓ Staging and rollout tests cover real hosting behavior

Make every request boundary dependable

Endurance Softwares helps teams build secure, high-performing Next.js applications with practical routing, authentication, observability, and release controls.

Discuss Your Next.js Architecture

Shares
Get Quote
Let's build something powerful

Have a project idea? Let’s turn it into a scalable product.

Book Free Consultation

© 2026 Endurance Softwares. All rights reserved.