logo
ia

Como tornar um site Next.js multilingue com next-intl: relato de experiência

4 min de leitura
Como tornar um site Next.js multilingue com next-intl: relato de experiência

Este artigo faz parte da série "Redesign de site com IA". Se não leu o primeiro episódio, comece por aí.


O problema

O meu site estava 100% em francês. Sem seletor de língua, sem estrutura multilingue, nada. No entanto, uma boa parte da minha rede profissional é anglófona, e as minhas origens brasileiras empurravam-me há muito tempo para adicionar o português.

A internacionalização de um site Next.js App Router é a obra que toda a gente adia. E com razão: toca em absolutamente tudo. As rotas, os layouts, os metadados, os componentes, o conteúdo. Cada ficheiro é impactado.


A base técnica: next-intl e o middleware

Primeiro passo: instalar next-intl e criar a infraestrutura de routing multilingue. O Claude Code gerou o middleware.ts com a deteção automática da língua do navegador e o redirecionamento para o locale apropriado. Criou o ficheiro i18n/routing.ts para configurar os locales (fr, en, pt) com o francês como língua por defeito, assim como i18n/request.ts para o carregamento dinâmico dos ficheiros de tradução conforme o locale ativo.


A migração de todas as rotas

Esta é a parte mais delicada. Cada página do site teve de ser movida para uma pasta app/[locale]/. A página inicial app/page.tsx passou a ser app/[locale]/page.tsx. A página do blog app/blog/page.tsx passou a ser app/[locale]/blog/page.tsx. E assim sucessivamente para cada rota do site.

Mas não se trata de uma simples mudança de ficheiros. Cada página teve de ser modificada para receber o parâmetro locale a partir das props, utilizar useTranslations() ou getTranslations() para os textos, e gerar metadados SEO na língua correta.


Mais de 385 chaves de tradução por língua

O Claude Code criou três ficheiros de tradução completos: messages/fr.json, messages/en.json e messages/pt.json. Cada um contém mais de 385 chaves que cobrem a navegação (menu principal, links, breadcrumbs), as páginas de serviço (Sprint, SaaS, Labs com cada secção, título e parágrafo), a página inicial (hero, serviços, testemunhos, FAQ), o blog (filtros, categorias, tempo de leitura, paginação), o SEO (title, description, OpenGraph para cada página) e toda a interface do utilizador (botões, formulários, página 404, footer).

Tudo coerente entre as três línguas, não uma tradução palavra por palavra mas uma verdadeira localização adaptada a cada cultura.


O LanguageSwitch

Um componente no footer que permite alternar entre línguas. Simples à primeira vista, mas com uma subtileza técnica: quando se está num artigo de blog, o switch deve levar à versão traduzida desse artigo (se existir) em vez de para a página inicial da língua de destino.

O Claude Code implementou um sistema de resolução de slugs alternativos através de um AlternatePathProvider que rastreia a correspondência entre os artigos e as suas traduções.


A armadilha dos slugs multilingues

Um problema que não se vê a chegar: certos artigos têm slugs diferentes conforme a língua. Quando se está em /fr/blog/2022/thibault-jaime e se muda para inglês, o URL deve passar a ser /en/blog/2022/thibault-jaime. Mas e se o ficheiro em inglês tiver um slug diferente?

O Claude Code resolveu isto adicionando um sistema de deteção que procura o ficheiro .en.mdx ou .pt.mdx correspondente ao mesmo id no frontmatter, independentemente da convenção de nomenclatura do ficheiro.


O resultado

Cada página do site está agora acessível em 3 línguas, com URLs limpos (/fr/blog/..., /en/blog/..., /pt/blog/...), metadados SEO localizados para cada página e cada língua, deteção automática da língua do navegador, navegação fluida entre as versões linguísticas, e filtragem de conteúdo por locale para que cada visitante veja apenas os artigos na sua língua.

Tudo isto sem partir nenhum URL existente graças aos redirecionamentos do middleware.


O tempo investido

Esta obra de i18n representou cerca de 2 horas de trabalho efetivo. Para pôr isto em perspetiva: a última vez que fiz uma internacionalização de raiz num projeto Next.js, tinha-me levado uma semana inteira.

A diferença? Não tive de escrever uma única chave de tradução manualmente. Não tive de migrar as rotas ficheiro a ficheiro. Não tive de fazer debug dos edge cases do middleware um por um. O Claude Code fez tudo isso, e eu ia revendo e orientando.


Amanhã, passamos a outro tipo de desafio: transformar 13 episódios de podcast em 50 artigos de blog. Como pode uma IA reciclar os seus podcasts em conteúdo SEO de qualidade? A resposta poderá surpreendê-lo.

Toni Dias

Toni Dias

Programador Full-Stack na AsuOs

Pronto para transformar o seu negócio digital?

A AsuOs apoia-o na sua estratégia digital com soluções à medida.