W3docs

JavaScript Intl (API de Internacionalização)

Aprenda a API Intl do JavaScript para formatar números, moedas, datas, tempos relativos, listas e plurais para qualquer locale, e ordenar strings corretamente com comparação sensível ao locale.

Intl é um namespace embutido do JavaScript para formatação e comparação sensíveis ao locale. Não há nenhuma biblioteca para instalar nem nada para importar — ele acompanha todos os navegadores modernos e o Node.js. Com ele você pode formatar números, moedas, datas, tempos relativos e listas exatamente da forma que os usuários de uma determinada região esperam, e pode ordenar texto corretamente para idiomas em que a ordenação baseada apenas em inglês falha.

Quase todos os construtores de Intl seguem a mesma estrutura: você passa um locale (ou um array de locales de fallback) e um objeto de opções. Um locale é uma tag de idioma BCP 47 como 'en-US', 'de-DE', 'fr-FR' ou 'ja-JP'. Se você omitir o locale completamente, o Intl usa o locale padrão do ambiente de execução (a configuração de idioma do navegador, ou o locale do sistema no Node).

// locale + options
new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' });

// no locale → uses the runtime default
new Intl.NumberFormat();

// an array provides fallbacks: try Welsh, then fall back to English
new Intl.NumberFormat(['cy', 'en']);

Intl.NumberFormat

Intl.NumberFormat formata números de acordo com as convenções de um locale. Isso é importante porque os separadores de agrupamento e decimais diferem de lugar para lugar: o número 1234.56 é escrito 1,234.56 nos Estados Unidos, mas 1.234,56 na Alemanha.

const n = 1234.56;

console.log(new Intl.NumberFormat('en-US').format(n)); // "1,234.56"
console.log(new Intl.NumberFormat('de-DE').format(n)); // "1.234,56"
console.log(new Intl.NumberFormat('fr-FR').format(n)); // "1 234,56"

A opção style seleciona que tipo de valor você está formatando: 'decimal' (o padrão), 'currency', 'percent' ou 'unit'.

Moeda

Para valores monetários, defina style: 'currency' e nomeie a moeda com a opção currency (um código ISO 4217 como 'USD' ou 'EUR'). O locale decide a posição do símbolo e os separadores.

const price = 1499.9;

console.log(
  new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(price)
); // "$1,499.90"

console.log(
  new Intl.NumberFormat('de-DE', { style: 'currency', currency: 'EUR' }).format(price)
); // "1.499,90 €"

console.log(
  new Intl.NumberFormat('ja-JP', { style: 'currency', currency: 'JPY' }).format(price)
); // "¥1,500"   (yen has no minor unit, so it is rounded)

Percentual, dígitos fracionários e notação compacta

Use style: 'percent' para formatar uma razão como percentual — o valor é multiplicado por 100. Controle quantas casas decimais aparecem com minimumFractionDigits e maximumFractionDigits. Defina notation: 'compact' para produzir formas abreviadas como 1.2K e 3.4M.

console.log(
  new Intl.NumberFormat('en-US', { style: 'percent' }).format(0.1875)
); // "19%"

console.log(
  new Intl.NumberFormat('en-US', {
    style: 'percent',
    minimumFractionDigits: 2,
  }).format(0.1875)
); // "18.75%"

console.log(
  new Intl.NumberFormat('en-US', { notation: 'compact' }).format(1200000)
); // "1.2M"

Unidades

Com style: 'unit' você pode formatar medidas. Nomeie a unidade com a opção unit (por exemplo 'kilometer-per-hour' ou 'megabyte') e escolha um unitDisplay de 'short', 'long' ou 'narrow'.

console.log(
  new Intl.NumberFormat('en-US', {
    style: 'unit',
    unit: 'kilometer-per-hour',
  }).format(90)
); // "90 km/h"

console.log(
  new Intl.NumberFormat('en-US', {
    style: 'unit',
    unit: 'megabyte',
    unitDisplay: 'long',
  }).format(16)
); // "16 megabytes"

Para trabalho mais aprofundado com números — arredondamento, precisão e aritmética — consulte Numbers e JavaScript Math.

Intl.DateTimeFormat

Intl.DateTimeFormat formata objetos Date (e timestamps) para um locale. A abordagem mais rápida são as opções dateStyle e timeStyle, cada uma aceitando 'full', 'long', 'medium' ou 'short'.

javascript— editable

Para um controle mais refinado, defina componentes individuais como year, month, day, hour, minute e second, e fixe a saída em um fuso horário com timeZone.

const date = new Date('2026-06-19T14:30:00Z');

const fmt = new Intl.DateTimeFormat('en-GB', {
  year: 'numeric',
  month: 'short',
  day: '2-digit',
  hour: '2-digit',
  minute: '2-digit',
  timeZone: 'Europe/Berlin',
});

console.log(fmt.format(date)); // "19 Jun 2026, 16:30"

Dois métodos extras valem a pena conhecer. .formatToParts() retorna a saída dividida em partes rotuladas ({ type: 'month', value: 'Jun' }, e assim por diante), o que permite reestilizar partes individuais. .formatRange(start, end) formata um intervalo de datas de forma compacta, recolhendo as partes em comum.

const fmt = new Intl.DateTimeFormat('en-US', { month: 'long', day: 'numeric' });

console.log(fmt.formatRange(new Date(2026, 5, 1), new Date(2026, 5, 5)));
// "June 1 – 5"

Para tudo sobre como criar e manipular datas, consulte JavaScript Date.

Intl.RelativeTimeFormat

Intl.RelativeTimeFormat produz frases como "2 dias atrás" ou "em 3 horas". Você chama .format(value, unit), onde um value negativo é no passado e um value positivo é no futuro. A opção numeric: 'auto' permite que o formatador use palavras como "yesterday" e "tomorrow" em vez de "1 day ago".

const rtf = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });

console.log(rtf.format(-1, 'day'));  // "yesterday"
console.log(rtf.format(3, 'hour'));  // "in 3 hours"
console.log(rtf.format(-2, 'day'));  // "2 days ago"
console.log(rtf.format(1, 'week'));  // "next week"

A mesma chamada em outro locale produz fraseamento nativo — new Intl.RelativeTimeFormat('fr').format(-1, 'day') resulta em "il y a 1 jour".

Intl.Collator

Ordenar texto é o ponto onde código ingênuo mais frequentemente erra. O Array.prototype.sort() padrão do JavaScript compara strings pelos seus code units UTF-16, não pelas regras alfabéticas. Isso significa que letras maiúsculas são ordenadas antes das minúsculas, e letras acentuadas ou não-latinas aparecem em lugares surpreendentes.

const words = ['Zürich', 'apple', 'Banana', 'Älpler'];

console.log([...words].sort());
// ["Banana", "Zürich", "Älpler", "apple"]  ← not what a reader expects

Intl.Collator corrige isso comparando strings da forma que um determinado idioma faz. Seu método .compare tem exatamente a assinatura que sort() espera, portanto você pode passá-lo diretamente.

javascript— editable

Para uma comparação pontual de duas strings você também pode usar String.prototype.localeCompare, que aceita os mesmos argumentos de locale e opções: 'ä'.localeCompare('z', 'de'). Quando você está ordenando um array inteiro, prefira um Intl.Collator reutilizado — é mais rápido do que chamar localeCompare em cada par. Consulte Strings para mais informações sobre como trabalhar com texto.

Intl.PluralRules

Idiomas diferentes têm categorias de plural diferentes. O inglês tem apenas duas ('one' e 'other'), mas muitos idiomas têm mais. Intl.PluralRules informa em qual categoria um número se enquadra para que você possa selecionar o texto correto em uma mensagem traduzida.

const pr = new Intl.PluralRules('en-US');

console.log(pr.select(0)); // "other"
console.log(pr.select(1)); // "one"
console.log(pr.select(5)); // "other"

function items(count) {
  const word = pr.select(count) === 'one' ? 'item' : 'items';
  return `${count} ${word}`;
}

console.log(items(1)); // "1 item"
console.log(items(3)); // "3 items"

Intl.ListFormat

Intl.ListFormat une um array de strings em uma lista com som natural, inserindo os separadores e a conjunção corretos para o locale — incluindo a vírgula de Oxford onde o idioma a utiliza.

const items = ['apples', 'bananas', 'oranges'];

const en = new Intl.ListFormat('en-US', { style: 'long', type: 'conjunction' });
console.log(en.format(items)); // "apples, bananas, and oranges"

const enOr = new Intl.ListFormat('en-US', { type: 'disjunction' });
console.log(enOr.format(items)); // "apples, bananas, or oranges"

const de = new Intl.ListFormat('de-DE', { type: 'conjunction' });
console.log(de.format(items)); // "apples, bananas und oranges"

Reutilize formatadores para melhor desempenho

Aviso

Construir um formatador Intl é relativamente custoso — ele carrega e resolve dados de locale. Crie cada formatador uma única vez e reutilize-o, especialmente dentro de loops ou renderização de listas. Construir um novo new Intl.NumberFormat(...) para cada linha pode ser muito mais lento do que a própria formatação.

// Slow: a new formatter is built on every iteration
prices.forEach((p) =>
  console.log(new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' }).format(p))
);

// Fast: build it once, reuse it
const money = new Intl.NumberFormat('en-US', { style: 'currency', currency: 'USD' });
prices.forEach((p) => console.log(money.format(p)));
Informação

Cada formatador também expõe .resolvedOptions(), que informa o locale e as opções efetivamente escolhidos após a negociação. É útil para depurar casos em que o ambiente de execução recorre a um locale diferente do solicitado.

Resumo

A API Intl cobre as tarefas de formatação e comparação que antes exigiam bibliotecas pesadas de terceiros: números, moedas, datas, tempos relativos, plurais e listas sensíveis ao locale, além de ordenação correta de texto via Intl.Collator. Por estar embutida em todos os navegadores modernos e no Node.js, usá-la em primeiro lugar mantém seu bundle pequeno e sua saída correta para usuários em qualquer lugar. Lembre-se da regra que mais compensa: construa cada formatador uma vez e reutilize-o.

Teste seus conhecimentos

Prática
Qual construtor Intl formata um número como moeda, e como?
Qual construtor Intl formata um número como moeda, e como?
Prática
Por que [...words].sort() pode colocar letras acentuadas ou maiúsculas na ordem errada, e o que resolve isso?
Por que [...words].sort() pode colocar letras acentuadas ou maiúsculas na ordem errada, e o que resolve isso?
Prática
Qual é a forma recomendada de usar um formatador Intl dentro de um loop?
Qual é a forma recomendada de usar um formatador Intl dentro de um loop?
Was this page helpful?