With Next.js 16, request interception has become clearer and more intentional through the introduction of the proxy.ts / proxy.js file convention. This new convention replaces the older middleware.ts naming and better reflects what the file actually does: intercepting and controlling requests before they are completed.
The proxy.ts file runs before a request reaches a page, layout, route handler, or static asset, making it ideal for authentication checks, redirects, rewrites, and request-level security logic. Because it runs at the Edge Runtime, it’s fast, scalable, and globally distributed.
What is proxy.ts in Next.js 16?
The proxy.ts file is a request interceptor that executes before Next.js finishes handling a request.
It allows you to:
- Redirect users
- Rewrite URLs
- Inspect headers, cookies, and request metadata
- Set response headers and cookies
- Block or allow access to routes
Unlike API routes or route handlers, proxy.ts is not meant for business logic or data fetching. Its role is control, not computation.
Where to add proxy.ts?
The proxy.ts (or proxy.js) file must be placed at the project root:
/
+-- app/
+-- proxy.ts
+-- next.config.js
+-- package.json
Important: Do not place proxy.ts inside the app directory. Next.js will not detect it there.
Understanding the Request Lifecycle
To use proxy.ts correctly, it’s important to understand when it runs:
- Request enters your Next.js app
- proxy.ts executes
- Routing, layouts, pages, and route handlers run
- Response is returned to the client
Creating a Basic proxy.ts File
import type { NextRequest } from "next/server";
import { NextResponse } from "next/server";
export function proxy(request: NextRequest) {
return NextResponse.next();
}This allows all requests to continue without modification. From here, you can layer in logic as needed.
Use Case 1: Protecting Authenticated Routes
One of the most common production uses of proxy.ts is route protection.
Example: Redirect unauthenticated users
import { NextResponse } from "next/server";
import type { NextRequest } from "next/server";
export function proxy(request: NextRequest) {
const token = request.cookies.get("auth_token");
const { pathname } = request.nextUrl;
if (!token && pathname.startsWith("/dashboard")) {
return NextResponse.redirect(
new URL("/login", request.url)
);
}
return NextResponse.next();
}What happens here:
- User opens /dashboard
- Proxy checks for a cookie called token
- If it doesn’t exist > user is redirected to /login
- If it exists > request continues
Use Case 2: Limiting Proxy Execution with matcher
By default, the proxy runs for every request, including static assets. In production, you should almost always limit this.
export const config = {
matcher: ["/dashboard/:path*", "/admin/:path*"],
};Now the proxy runs only for:
- /dashboard
- /dashboard/*
- /admin
- /admin/*
This improves performance and keeps logic scoped.
Use Case 3: Rewriting Requests
Rewrites let you change where a request goes without changing the URL in the browser.
export function proxy(request: NextRequest) {
if (request.nextUrl.pathname === "/api/public") {
return NextResponse.rewrite(
new URL("/api/internal", request.url)
);
}
return NextResponse.next();
}The browser still sees:
/api/public
But Next.js internally uses:
/api/internal
Common rewrite scenarios:
- API versioning
- Feature flags
- Internal route restructuring
Use Case 4: Modifying Headers and Cookies
Because proxy.ts runs at the edge, it’s ideal for lightweight response mutations.
Adding a response header
export function proxy() {
const response = NextResponse.next();
response.headers.set("x-app-env", "production");
return response;
}Setting a cookie
export function proxy() {
const response = NextResponse.next();
response.cookies.set("visited", "true", {
httpOnly: true,
secure: true,
});
return response;
}What proxy.ts Should NOT Be Used For
Despite its power, proxy.ts has clear limitations.
- Database access
- Complex business logic
- Calling third-party APIs
- Acting as a backend API proxy
For these use cases, use:
- Route Handlers (app/api/*)
- Server Actions
- External backend services
The proxy.ts file in Next.js 16 is a powerful but focused tool. It gives you early, centralized control over requests, making your application more secure, faster, and easier to reason about.
To read more about How to Handle Loading and Error States in Next.js Server Components, refer to our blog How to Handle Loading and Error States in Next.js Server Components.