proxy.ts in Next.js — The Silent Guardian at the Edge

The proxy.ts file in Next.js replaces middleware.ts and acts as an edge-level gatekeeper before your app renders. It can rewrite or redirect routes, set headers and cookies, block access, and run background tasks. This article explains how to use proxy.ts, define precise matchers, and implement real-world scenarios like authentication, A/B testing, CORS, and geo-based redirects.

matcherNextResponseEdge Middleware

~2 min read • Updated Dec 12, 2025

1. Why proxy.ts?


Next.js renamed middleware.ts to proxy.ts to avoid confusion with Express and clarify its role as a network-level proxy that runs at the edge before your app loads.


2. What Can proxy.ts Do?


ActionCode
RedirectNextResponse.redirect()
RewriteNextResponse.rewrite()
Set Headersresponse.headers.set()
Set Cookiesresponse.cookies.set()
Block Accessreturn new Response('401')
Log Analyticsevent.waitUntil(fetch(...))

3. Basic Setup


// proxy.ts
import { NextResponse, NextRequest } from 'next/server'

export function proxy(request: NextRequest) {
  return NextResponse.redirect(new URL('/home', request.url))
}

export const config = {
  matcher: '/about/:path*',
}

4. matcher — Be Precise


  • Single path: '/about'
  • Multiple: ['/dashboard', '/profile']
  • Wildcard: '/blog/:path*'
  • Regex: '/(?!api|_next/static).*'

5. Real-World Examples


5.1 Auth Guard

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

5.2 A/B Testing

url.pathname = random < 0.5 ? '/experiments/a' : '/experiments/b'

5.3 Geo Redirect

if (country === 'IR') {
  return NextResponse.rewrite(new URL('/fa', request.url))
}

5.4 CORS for APIs

response.headers.set('Access-Control-Allow-Origin', origin)

5.5 Security Headers

response.headers.set('X-Frame-Options', 'DENY')

6. Background Tasks with waitUntil


event.waitUntil(fetch('https://analytics.com/log', { method: 'POST', body: ... }))

7. Testing proxy.ts


unstable_doesProxyMatch({ config, url: '/dashboard' })

8. Best Practices


DoDon’t
Use precise matchersRun on every route
Return earlyRun heavy logic
Use waitUntil for logsBlock response
Set cookies/headersDepend on global state
Keep it statelessShare app modules

9. Migration from middleware.ts


npx @next/codemod@canary middleware-to-proxy .

10. When to Use proxy.ts?


Use CaseUse proxy?
Auth redirect
A/B testing
Feature flags
Logging✅ (with waitUntil)
Rate limiting✅ (at edge)
SEO redirects
Page rendering❌ use Server Components

Written & researched by Dr. Shahin Siami