Capítulo 239 de 456

rewrites

Core Idea

Mapeia um path de requisição para um destino diferente sem trocar a URL visível (age como proxy). Diferente de redirects, rewrites se aplicam a client-side routing e podem apontar para URLs externas.

Key Concepts

  • rewrites(): função sync/async retornando array (comportamento simples) ou objeto { beforeFiles, afterFiles, fallback } (controle fino, desde v10.1) de objetos { source, destination, basePath, locale, has, missing }.
  • Mesmos campos source/destination/has/missing/basePath/locale de redirects, mesma sintaxe de path matching (wildcard */+/?, regex entre parênteses, escape de caracteres especiais).

Ordem de resolução de rotas

  1. headers verificados/aplicados
  2. redirects verificados/aplicados
  3. proxy
  4. beforeFiles rewrites (checa TODOS antes de tocar no filesystem/dynamic routes)
  5. arquivos estáticos (public/, _next/static) e páginas não-dinâmicas
  6. afterFiles rewrites (primeiro que resolver para arquivo estático/página/rota dinâmica é servido)
  7. rotas dinâmicas (app/blog/[slug]/page.tsx)
  8. fallback rewrites (antes da página 404; getStaticPaths com fallback: true/'blocking' tem prioridade sobre isso)

Rewrite Parameters

  • Se nenhum parâmetro do source é usado no destination, todos são passados automaticamente na query.
  • Se algum parâmetro É usado no destination, NENHUM é passado automaticamente — precisa adicionar manualmente (destination: '/:first?second=:second').

Rewriting to an external URL

Útil para adoção incremental do Next.js: destination pode ser uma URL externa completa (https://example.com/blog/:slug). Com trailingSlash: true, source (e destination, se o servidor externo exigir) também precisam da barra final. fallback combinado com destino externo permite fazer proxy total pro site legado após checar todas as rotas Next.js, sem precisar reconfigurar rewrites ao migrar mais páginas.

Code Examples

module.exports = {
  rewrites() {
    return {
      beforeFiles: [{ source: '/some-page', destination: '/somewhere-else', has: [{ type: 'query', key: 'overrideMe' }] }],
      afterFiles: [{ source: '/non-existent', destination: '/somewhere-else' }],
      fallback: [{ source: '/:path*', destination: 'https://my-old-site.com/:path*' }],
    }
  },
}
module.exports = {
  rewrites() {
    return [{ source: '/blog', destination: 'https://example.com/blog' }]
  },
}
  • O que demonstra: forma de objeto com as três fases de matching, e rewrite simples para URL externa (adoção incremental).

Reference Tables

FaseQuando é checada
beforeFilesapós headers/redirects, antes de qualquer arquivo (_next, public, páginas)
afterFilesapós arquivos/páginas, antes de rotas dinâmicas
fallbackapós páginas/arquivos estáticos E rotas dinâmicas, antes do 404

Version History

VersãoMudança
v13.3.0missing adicionado.
v10.2.0has adicionado.
v9.5.0Headers adicionado.

Key Takeaways

  1. Rewrites afetam client-side routing (<Link>); redirects não, a menos que proxy esteja envolvido.
  2. basePath: false numa rewrite para URL externa não pode ser usado para rewrite interno (destination: '/another').
  3. Params de páginas estáticas (Automatic Static Optimization/prerendering) resolvidos via rewrite são parseados no client após hidratação, disponíveis na query.

Connects To

  • redirects (ch238): compartilha sintaxe de source/has/missing, mas rewrite mascara a URL em vez de trocá-la.
  • headers: checados antes de redirects e rewrites na ordem de resolução.
  • proxy: verificado logo após redirects, antes de beforeFiles.
  • basePath: prefixa source/destination automaticamente salvo basePath: false.