Capítulo 125 de 456
proxy.js|ts (renomeado de middleware na v16) roda código no servidor antes de a rota ser renderizada, permitindo rewrite, redirect, alteração de headers/cookies ou resposta direta. Fica na raiz do projeto (ou dentro de src), no mesmo nível de app/pages.
proxy function: export default ou nomeado proxy; recebe request (NextRequest) e event (NextFetchEvent).config.matcher: define em quais paths o Proxy roda; sem matcher, roda em toda requisição, inclusive assets estáticos.event.waitUntil(promise): estende o ciclo de vida do Proxy até a promise resolver, útil para logging/analytics em background.NextResponse: API para redirect, rewrite, setar headers/cookies de request e response.runtime não é suportada em arquivos Proxy (lança erro se setada).skipTrailingSlashRedirect e skipProxyUrlNormalize: flags de next.config.js para casos avançados de migração incremental e controle total da URL.import { NextResponse } from 'next/server'
import type { NextRequest } from 'next/server'
export function proxy(request: NextRequest) {
return NextResponse.redirect(new URL('/home', request.url))
}
export const config = {
matcher: '/about/:path*',
}
matcher.export const config = {
matcher: [
'/((?!api|_next/static|_next/image|favicon.ico|sitemap.xml|robots.txt).*)',
],
}
npx @next/codemod@canary middleware-to-proxy .
middleware.ts → proxy.ts.headers do next.config.jsredirects do next.config.jsbeforeFiles rewrites do next.config.jspublic/, _next/static/, pages/, app/)afterFiles rewrites do next.config.jsfallback rewrites do next.config.js| Deployment | Suportado |
|---|---|
| Node.js server | Sim |
| Docker container | Sim |
| Static export | Não |
| Adapters | Depende da plataforma |
matcher para proteger Server Functions: elas são requisições POST para a rota onde são usadas; um matcher que exclui um path também pula a Server Function ali. Sempre valide autenticação/autorização dentro da própria Server Function.NextResponse.next({ headers: requestHeaders }) para propagar headers upstream: isso expõe o header ao cliente; o correto é NextResponse.next({ request: { headers: requestHeaders } }).fetch() sem repassar headers RSC: NextResponse.rewrite() já propaga os headers de Flight necessários; fetch manual perde rsc, next-router-state-tree etc a menos que sejam repassados ou skipProxyUrlNormalize seja usado._next/data no matcher bloqueia o Proxy nessa rota: Next.js sempre invoca o Proxy para _next/data, intencionalmente, para não deixar a rota de dados desprotegida enquanto a página está protegida.matcher precisa ser um valor estático (constante) para ser analisado em build-time — variáveis dinâmicas são ignoradas.unstable_doesProxyMatch, isRewrite e getRewrittenUrl (de next/experimental/testing/server) para testar o Proxy sem subir o servidor.proxy.js.