Renderização Estática vs Dinâmica com i18n no Next.js
O problema com o next-intl
O que acontece? Quando você usa
useTranslations,getTranslationsou qualquer helper do next-intl dentro de um Componente de Servidor em um app com rotas i18n (/en/…,/fr/…), o Next.js marca toda a rota como dinâmica. ([Next Intl][1])Por quê? next-intl busca a localidade atual a partir de um cabeçalho disponível apenas na requisição (
x-next-intl-locale) viaheaders(). Comoheaders()é uma API dinâmica, qualquer componente que a utilize perde a otimização estática. ([Next Intl][1], [Next.js][2])Solução oficial (boilerplate)
- Exporte
generateStaticParamscom todas as localidades suportadas. - Chame
setRequestLocale(locale)em todos os layouts/páginas antes de chamaruseTranslations. ([Next Intl][1]) Isso remove a dependência do cabeçalho, mas agora você tem código extra para manter e uma API instável em produção.
- Exporte
Como o intlayer evita o problema
Escolhas de design
- Apenas parâmetro de rota – A localidade vem do segmento de URL
[locale]que o Next.js já passa para cada página. - Pacotes em tempo de compilação – As traduções são importadas como módulos ES regulares, portanto são otimizadas (tree-shaken) e incorporadas no momento da compilação.
- Sem APIs dinâmicas –
useT()lê do contexto React, não deheaders()oucookies(). - Configuração zero – Uma vez que suas páginas estejam sob
app/[locale]/, o Next.js pré-renderiza automaticamente um arquivo HTML por localidade.