Skip to the solution
MediumSystem Design6 min read

What is Middleware in Next.js and what can it do?

853 views

The problem

Question presented to candidate: "What is middleware in Next.js, what is it good for and what should it not do? And what changed with Next.js 16?"

What a strong answer should cover:

  • Middleware runs code before a request reaches a route, for paths chosen with a matcher.
  • It can redirect, rewrite to another path, set request and response headers or cookies, or return a response directly.
  • Typical uses: auth redirects based on a cookie, locale or A/B routing, bot filtering, adding security headers.
  • It should stay fast and light: no heavy data fetching or full authorization logic; verify permissions again close to the data.
  • In Next.js 16 the file is proxy.ts with a proxy function, running on Node.js by default; middleware.ts is deprecated and still runs on the Edge runtime.

Clarifying questions expected:

  • "Is this for every request or only some paths?" β€” decides the matcher.
  • "Which Next.js version?" β€” decides the file name and the runtime.

Code / implementation expected: Yes β€” a proxy.ts with a matcher, a redirect, a rewrite and a header.

  • nextjs
  • middleware
  • edge
  • auth

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

6 min read Β· 8 sections

Read the code

A proxy.ts with an auth gate, a rewrite and a security header
// proxy.ts (project root, Next.js 16)
import { NextRequest, NextResponse } from "next/server";

export function proxy(req: NextRequest) {
  const { pathname } = req.nextUrl;

  if (pathname.startsWith("/dashboard") && !req.cookies.get("session")) {
    return NextResponse.redirect(new URL(`/login?next=${pathname}`, req.url));
  }
  if (pathname === "/old-pricing") {
    return NextResponse.rewrite(new URL("/pricing", req.url));
  }

  const res = NextResponse.next();
  res.headers.set("x-frame-options", "DENY");
  return res;
}

export const config = {
  matcher: ["/((?!_next/static|_next/image|favicon.ico).*)"],
};

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 46 of 129 in Next.js

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

All Next.js questions
Up nextMedium

What is the difference between the App Router and the Pages Router?

Continue