A API de Internacionalização do JavaScript (Intl)

Descubra como usar a API Intl nativa do JavaScript para formatar números, datas, listas e plurais de forma eficiente sem depender de bibliotecas de terceiros.

A API de Internacionalização do JavaScript (Intl)
6 min de leitura
Nesta página

Resumo

A internacionalização (i18n) em JavaScript dependia historicamente de bibliotecas externas pesadas, como Moment.js ou date-fns. A API Intl (disponível nativamente em todos os navegadores modernos) resolve isso oferecendo formatação numérica, manipulação de datas, ordenação de strings e segmentação diretamente no motor do JavaScript.

Este artigo explora os construtores-chave do namespace Intl, ensinando como adaptar suas aplicações para múltiplas culturas com zero dependências.


1. O objeto global Intl

O objeto global Intl atua como um namespace (semelhante ao Math). Não pode ser instanciado com new. Em vez disso, abriga vários construtores especializados.

Quase todos esses construtores aceitam dois parâmetros:

  • locales: uma string com o código BCP 47 (ex.: "pt-BR", "en-GB") ou um array deles. Se omitido, usa o locale do sistema do usuário.
  • options: um objeto de configuração para ajustar o comportamento do construtor.

2. Formatação de Números e Moedas (Intl.NumberFormat)

O construtor Intl.NumberFormat formata números com base em convenções regionais (separadores de milhar, decimais, etc.).

2.1 Moedas e Porcentagens

Configurando a propriedade style, podemos formatar finanças ou unidades sem concatenar strings manualmente:

const amount = 123456.789;

// Formato português (Brasil) - usa vírgula para decimais
const formatPT = new Intl.NumberFormat('pt-BR');
console.log(formatPT.format(amount)); // "123.456,789"

// Formato de moeda (Reais)
const formatReal = new Intl.NumberFormat('pt-BR', {
  style: 'currency',
  currency: 'BRL'
});
console.log(formatReal.format(amount)); // "R$ 123.456,79"

// Formato contábil dos EUA (números negativos entre parênteses)
const formatAccounting = new Intl.NumberFormat('en-US', {
  style: 'currency',
  currency: 'USD',
  currencySign: 'accounting'
});
console.log(formatAccounting.format(-amount)); // "($123,456.79)"

2.2 Unidades Físicas

Podemos formatar unidades padronizadas (quilômetros, litros, bytes) de forma nativa:

const speed = new Intl.NumberFormat('pt-BR', {
  style: 'unit',
  unit: 'kilometer-per-hour',
  unitDisplay: 'long'
});
console.log(speed.format(120)); // "120 quilômetros por hora"

3. Pluralização (Intl.PluralRules)

Diferentes idiomas possuem regras gramaticais de pluralização altamente complexas. O Intl.PluralRules não retorna uma string formatada, mas classifica um número em categorias ("zero", "one", "two", "few", "many", "other"), que você pode usar como chaves para o seu sistema de traduções.

const arabicRules = new Intl.PluralRules('ar-EG');
console.log(arabicRules.select(0));  // "zero"
console.log(arabicRules.select(1));  // "one"
console.log(arabicRules.select(2));  // "two"
console.log(arabicRules.select(6));  // "few"

// Uso de ordinais em inglês (1st, 2nd, 3rd)
const ordinalRulesEN = new Intl.PluralRules('en-US', { type: 'ordinal' });
console.log(ordinalRulesEN.select(1)); // "one" (para o sufixo "st")
console.log(ordinalRulesEN.select(2)); // "two" (para o sufixo "nd")
console.log(ordinalRulesEN.select(3)); // "few" (para o sufixo "rd")
console.log(ordinalRulesEN.select(4)); // "other" (para o sufixo "th")

4. Manipulação do Tempo

O tempo é gerenciado de forma abrangente através de três pilares na API Intl:

4.1 Formatadores Absolutos: Intl.DateTimeFormat

Converte datas em texto humano de acordo com horários e calendários regionais. Suporta macros como dateStyle e timeStyle para simplificar as opções.

const date = new Date(Date.UTC(2026, 0, 10, 10, 0, 0));

const fullFormat = new Intl.DateTimeFormat('pt-BR', {
  dateStyle: 'full',
  timeStyle: 'long',
  timeZone: 'America/Sao_Paulo'
});
console.log(fullFormat.format(date));
// "sábado, 10 de janeiro de 2026 às 07:00:00 BRT"

// Suporta intervalos sem redundâncias temporais
const endDate = new Date(Date.UTC(2026, 0, 12, 10, 0, 0));
const rangeFormat = new Intl.DateTimeFormat('pt-BR', { dateStyle: 'long' });
console.log(rangeFormat.formatRange(date, endDate));
// "10 a 12 de janeiro de 2026"

4.2 Tempo Relativo: Intl.RelativeTimeFormat

Adequado para exibir tempos relativos na interface (“há 5 minutos”, “ontem”).

const relativeTime = new Intl.RelativeTimeFormat('pt-BR', { numeric: 'auto' });

console.log(relativeTime.format(-1, 'day')); // "ontem"
console.log(relativeTime.format(2, 'day'));  // "depois de amanhã"
console.log(relativeTime.format(-3, 'month')); // "há 3 meses"

4.3 Durações: Intl.DurationFormat

Exibe a duração de um intervalo independentemente do contexto da data. Recebe objetos da nova especificação Temporal.

const span = { hours: 2, minutes: 4, seconds: 35 };

const stopwatch = new Intl.DurationFormat('en-US', {
  style: 'digital',
  hoursDisplay: 'always',
  minutes: '2-digit'
});
console.log(stopwatch.format(span)); // "2:04:35"

5. Manipulação de Strings e Dados

5.1 Ordenação Natural: Intl.Collator

Resolve as deficiências do .sort() padrão dos arrays, ordenando números e ignorando acentos corretamente.

const docs = ['arquivo10.txt', 'arquivo2.txt', 'Álbum.txt', 'Zebra.txt'];

// Array.sort() falhará ao colocar "10" antes do "2", e a "Á" no final.
// Intl.Collator corrige isso:
const collator = new Intl.Collator('pt-BR', { numeric: true, sensitivity: 'base' });
docs.sort(collator.compare);

console.log(docs);
// ["Álbum.txt", "arquivo2.txt", "arquivo10.txt", "Zebra.txt"]

5.2 Formatação de Listas: Intl.ListFormat

Gera as conjunções ou disjunções corretas de acordo com o idioma (“e”, “ou”, dependendo do locale).

const ingredients = ['Farinha', 'Ovos', 'Açúcar'];

const formatterPT = new Intl.ListFormat('pt-BR', { type: 'conjunction' });
console.log(formatterPT.format(ingredients)); // "Farinha, Ovos e Açúcar"

const formatterEN = new Intl.ListFormat('en-US', { type: 'conjunction' });
console.log(formatterEN.format(ingredients)); // "Farinha, Ovos, and Açúcar"

5.3 Segmentação Inteligente: Intl.Segmenter

Identificar os limites das palavras usando .split(' ') falha com linguagens logográficas (como japonês ou chinês), ou com emojis compostos por múltiplos glifos.

const japaneseText = "吾輩は猫である。名前はたぬき。";

const segmenter = new Intl.Segmenter('ja-JP', { granularity: 'word' });
const segments = segmenter.segment(japaneseText);

for (const chunk of segments) {
  if (chunk.isWordLike) {
    console.log(chunk.segment);
    // Exibe "吾輩", "は", "猫", "で", "ある", "名前", "は", "たぬき"
  }
}

5.4 Nomes de Regiões e Idiomas: Intl.DisplayNames

Evita carregar grandes dicionários JSON ao traduzir de forma nativa os nomes de idiomas, regiões ou moedas.

const regionTranslator = new Intl.DisplayNames(['pt-BR'], { type: 'region' });
console.log(regionTranslator.of('US')); // "Estados Unidos"
console.log(regionTranslator.of('JP')); // "Japão"

const languageTranslator = new Intl.DisplayNames(['en-US'], { type: 'language' });
console.log(languageTranslator.of('es-419')); // "Latin American Spanish"

6. Desempenho e Caching

Inicializar construtores do namespace Intl é uma operação relativamente dispendiosa em termos de desempenho.

Se sua aplicação realiza a mesma formatação intensamente (por exemplo, ao mapear milhares de transações para a interface), nunca instancie a classe dentro do loop iterativo.

Padrão recomendado de Caching:

const prices = [10.5, 20.9, 100, 450.2];

// ✅ CORRETO: Instanciamos o objeto formatador UMA única vez fora do loop.
const formatBRL = new Intl.NumberFormat('pt-BR', { style: 'currency', currency: 'BRL' });

const renderOutput = prices.map(price => formatBRL.format(price));

7. Conclusão

A API Intl do ECMAScript é a abordagem padrão para a internacionalização de aplicações web e Node.js. Ao transferir as dependências algorítmicas para o motor do navegador ou servidor, a Intl elimina a necessidade de bibliotecas adicionais, resultando em aplicações mais eficientes, robustas e resilientes diante das mudanças contínuas nas convenções regionais.


Fontes: MDN Web Docs, Especificação ECMA-402 API de Internacionalização.

Arraste para mover o diagrama. Use + e − para dar zoom, as setas para movê-lo e 0 para redefinir a visualização.

Vamos trabalhar juntos

Engenheiro de Software e desenvolvedor Senior Full-Stack, trabalho remotamente a partir de Santa Cruz, Bolívia. Aberto a novas oportunidades.