O ICU MessageFormat é um padrão Unicode para escrever uma única string traduzível que se adapta a quantidade, gênero e outras variáveis, e ainda é difícil de traduzir porque a sintaxe foi projetada para código, não para as pessoas que fazem a localização. A especificação existe há bem mais de uma década, e quem mais tropeça nela são tradutores não técnicos diante de chaves aninhadas. O globalize.now é uma infraestrutura de localização com IA que atua uma camada abaixo desse problema: ele extrai as strings e gera os arquivos de idioma onde esses padrões ICU vivem, mantendo-os sincronizados a cada push no Git.

O que é o ICU MessageFormat?

O ICU MessageFormat é uma sintaxe para expressar uma mensagem cuja redação final depende de dados de runtime. Em vez de concatenar fragmentos no código, você escreve um único padrão e deixa o formatador escolher o ramo correto para cada idioma.

O uso mais comum é a pluralização:

{count, plural,
  one {You have # message}
  other {You have # messages}
}

O # é substituído pelo número, e os ramos one / other correspondem às categorias de plural de um idioma. O inglês tem duas; o polonês, o russo e o árabe têm mais. O ICU também lida com gênero e outras escolhas por meio de select:

{gender, select,
  male {He liked your post}
  female {She liked your post}
  other {They liked your post}
}

É por isso que o ICU se tornou o padrão de fato para pluralização: ele empurra a complexidade gramatical para dentro de dados que podem variar por idioma, em vez de embuti-la em uma lógica condicional que só funciona para o idioma em que foi escrita. Bibliotecas de runtime como FormatJS, i18next e next-intl entendem esse formato.

Por que o ICU MessageFormat é tão difícil de traduzir?

É difícil de traduzir porque a sintaxe foi criada para desenvolvedores, e quem de fato traduz as strings geralmente não é desenvolvedor.

Um tradutor que abre um arquivo de idioma não vê “Você tem 3 mensagens.” Ele vê chaves, as palavras-chave plural e select, categorias de plural que talvez ele não reconheça, e um placeholder # que parece um erro de digitação. Um colchete apagado ou uma categoria renomeada, e a string lança um erro em tempo de execução em vez de renderizar. A mesma estrutura que torna o ICU poderoso para engenheiros é a que o torna frágil nas mãos de um linguista.

Essa é a lacuna com a qual o setor de localização convive silenciosamente há anos. A maioria das ferramentas lida com isso mostrando o padrão bruto e torcendo para que o tradutor não mexa no caractere errado, ou escondendo as formas de plural atrás de um editor separado que ainda assim exige que o tradutor entenda categorias de plural. Nenhum fornecedor conseguiu fechar por completo a distância entre a complexidade da especificação e o modelo mental de um tradutor não técnico.

O que mudou com o MessageFormat 2.0?

O MessageFormat 2.0 é um redesenho da sintaxe feito do zero, e em 2025 ele se tornou um padrão estável, deixando de ser apenas um rascunho.

O MF2 atingiu o status de Candidato Final em março de 2025 e agora faz parte estável do CLDR, publicado como parte do padrão técnico Unicode LDML e aprimorado nas versões LDML 47 e 48. A implementação de referência acompanha a especificação a partir da versão LDML 48.2, lançada no início de 2026. A nova sintaxe separa as entradas da lógica de correspondência e oferece suporte a funções de formatação nomeadas, o que torna mensagens complexas mais legíveis:

.input {$count :number}
.match $count
one {{You have {$count} message}}
*   {{You have {$count} messages}}

A intenção é ter um padrão mais fácil de estender e um pouco menos hostil de ler do que as chaves aninhadas originais.

O MessageFormat 2.0 resolve o problema do tradutor?

Ainda não, por dois motivos.

Primeiro, o MF2 melhora a ergonomia da sintaxe, mas ainda é sintaxe. Um tradutor ainda vai encontrar .match, chaves de plural e chaves. A carga cognitiva é menor do que no MF1, mas não desapareceu, e um tradutor não técnico ainda pode quebrar uma mensagem editando o token errado.

Segundo, quase ninguém está usando isso em produção. A adoção segue limitada mesmo já em 2026: o processo do TC39 para o lado JavaScript quer ver algo em torno de uma dezena de organizações usando o MF2 em produção antes de avançar mais, e esse patamar ainda não foi atingido. Na prática, a maioria dos aplicativos que você coloca no ar hoje ainda roda sobre o ICU MessageFormat original, por meio de bibliotecas como FormatJS e i18next. Então o problema voltado ao tradutor não é resolvido por uma especificação; ele é resolvido por onde a sintaxe é produzida e mantida.

Onde o ICU MessageFormat quebra em aplicativos gerados por IA?

Ele quebra logo no início, porque ferramentas de codificação com IA raramente geram um ICU correto desde o começo.

Quando você constrói com Cursor, Claude Code ou Lovable, o código gerado tende a lidar com quantidades da forma ingênua:

// What an AI coding tool often generates
const label = count + " " + (count === 1 ? "message" : "messages");

Essa lógica é correta para o inglês e errada para a maioria das outras línguas, porque ela pressupõe exatamente duas formas de plural. Ela também engessa a frase dentro do código da aplicação, então não há nenhum padrão ICU em um arquivo de idioma para o tradutor localizar. A string fica invisível para a camada de localização até alguém notar o erro de gramática em produção. Ferramentas de IA também duplicam chaves e espalham texto fixo pelos componentes, então até times que querem usar ICU acabam com strings que nunca chegaram a um arquivo traduzível. A visão geral para desenvolvedores do globalize.now foi criada exatamente para detectar esse tipo de string antes que ela vá para produção.

Como os desenvolvedores devem lidar com o ICU MessageFormat em 2026?

Trate o ICU como infraestrutura gerada, não como conteúdo escrito manualmente.

A regra prática: desenvolvedores e ferramentas de IA não deveriam escrever concatenação de plural no código, e tradutores não deveriam editar manualmente as chaves brutas do ICU. O padrão ICU pertence a um arquivo de idioma gerado e mantido atualizado automaticamente, e então renderizado em tempo de execução por uma biblioteca como FormatJS, i18next ou next-intl. Isso mantém a sintaxe correta no momento em que é criada e consistente em todos os idiomas conforme o app evolui. Se você está avaliando onde o ICU se encaixa em relação à sua camada de runtime, a comparação globalize.now vs i18next mostra como infraestrutura e runtime dividem o trabalho.

É nessa camada que o globalize.now atua. Ele extrai strings fixas do seu código, gera as chaves e os arquivos de idioma onde ficam os padrões ICU, e os ressincroniza a cada push no Git, mantendo a estrutura correta sem nenhuma etapa manual de exportação. Ele não tenta ser o editor do tradutor nem substituir sua biblioteca de runtime; ele garante que os arquivos no formato ICU dos quais essas ferramentas dependem realmente existam e permaneçam sincronizados. O guia para vibe-coders apresenta a mesma configuração para apps construídos com Lovable, Bolt e Replit, e o fluxo completo está na página inicial do globalize.now.

O globalize.now transforma textos fixos do app em arquivos de locale prontos para tradução e os mantém atualizados a cada novo lançamento.

Experimente o globalize.now grátis