← Voltar aos artigos

Falar Todas as Línguas: Como Funciona a Localização neste Starter

A localização não é uma funcionalidade que se acrescenta depois do lançamento. É uma decisão tomada ao nível da arquitetura — no routing, no modelo de conteúdo e nas ferramentas do Studio. Este starter toma essa decisão por ti, ligando next-intl e @tinloof/sanity-document-i18n para que toda a stack fale todas as línguas desde o primeiro dia.

Pedro Duque
Pedro Duque
localization

1. As Duas Camadas de i18n

Há dois problemas distintos ao construir um site multilíngue.

  • Traduções da UI — labels, navegação, formatos de datas, plurais. Estas vivem no código.
  • Traduções de conteúdo — artigos, páginas, copy de marketing. Estas vivem no CMS.

A maioria dos starters resolve apenas um deles e deixa o outro como “exercício para o leitor”. Este resolve ambos.

2. Camada de UI: next-intl

next-intl trata de tudo o que pertence ao código:

  • Routing com prefixo de locale — /en/about, /pt/sobre, /pl/o-nas
  • Catálogos de mensagens tipados via ficheiros JSON por locale
  • Pluralização, formatação de datas e números
  • Suporte nativo para React Server Components
  • Um único middleware que negocia o locale, faz redirects e liga tudo

A configuração de routing vive num único ficheiro e é partilhada entre o middleware e as APIs de navegação. Ao adicionar um locale, o routing, os redirects e os links alternativos atualizam automaticamente.

A negociação de locale segue uma ordem clara de prioridade: primeiro o prefixo na URL, depois um cookie guardado, depois o header Accept-Language do browser e, por fim, o default configurado. Os utilizadores entram logo na língua correta na primeira visita e mantêm-na nas seguintes.

Dentro de Server Components, as traduções são carregadas por request e totalmente tipadas com base nos catálogos. Em Client Components, a mesma API está disponível de forma síncrona. Um provider no layout raiz faz a ponte entre servidor e cliente para evitar duplicação de mensagens no bundle.

3. Camada de Conteúdo: @tinloof/sanity-document-i18n

As strings da UI são apenas metade da história. O conteúdo escrito no Sanity Studio também precisa de ser traduzível, revisto e publicado por locale.

@tinloof/sanity-document-i18n é um fork da comunidade do plugin oficial @sanity/document-internationalization, melhorado com gestão de templates e uma configuração mais opinativa para traduções ao nível de documento.

O plugin adiciona:

  • Um separador de Translations no editor — um documento por locale, ligado por metadata de tradução
  • Um badge de língua em cada documento para os editores saberem sempre em que idioma estão a trabalhar
  • Lógica de fallback — traduções em falta regressam ao idioma default
  • Preview por locale no Sanity Studio — ver exatamente como a página fica em cada língua antes de publicar
  • Templates iniciais por locale para novos documentos já começarem configurados corretamente

Cada tipo de documento traduzível é registado na configuração do plugin juntamente com a lista de idiomas suportados. Cada documento inclui depois um campo oculto de linguagem que as queries GROQ usam para filtrar conteúdo por locale — limpo, explícito e previsível.

4. Como as Duas Camadas se Ligam

O segmento de locale na URL é a única fonte de verdade.

O middleware do next-intl lê o request, negocia o locale e disponibiliza-o a todos os Server Components na árvore.

A camada de dados usa esse mesmo locale para consultar o Sanity e obter os documentos na língua correta. O locale flui de cima para baixo — da URL para o layout, para o catálogo de traduções da UI e para a query GROQ que obtém o documento certo. Sem magia escondida, sem divergências entre router e CMS.

5. Adicionar um Novo Locale

Estender o starter para uma nova língua é um processo de três passos:

  • Adicionar ao config de routing — o novo prefixo de URL fica ativo de imediato
  • Adicionar um novo ficheiro de mensagens — por exemplo messages/de.json — para strings da UI
  • Adicionar à lista de idiomas suportados no plugin — os editores podem agora criar documentos nesse idioma no Studio

Sem alterações a layouts, sem alterações a componentes de página, sem alterações a queries. A arquitetura absorve novos idiomas sem tocar no código da aplicação.

Porque Isto Importa

A maioria das configurações de localização está dividida em dois sistemas sem contrato partilhado — o frontend trata do routing, o CMS trata do conteúdo, e os dois raramente concordam em identificadores de locale ou regras de fallback.

Este starter faz com que concordem por design:

  • A lista de locais é definida uma vez no routing e espelhada na configuração do Sanity
  • next-intl trata da camada de routing e UI sem código adicional
  • @tinloof/sanity-document-i18n trata da camada de conteúdo com previews e fallback por locale
  • As queries GROQ são locale-aware desde o início — sem necessidade de adaptação

O resultado é uma stack onde adicionar uma nova língua é algo aditivo, não invasivo. Os editores trabalham num Studio que mostra o locale correto. Os developers fazem queries a um CMS que devolve os documentos certos. Os utilizadores entram em URLs que falam a sua língua.

Esse é o contrato que este starter impõe — e ele mantém-se consistente à escala.