Ir para o conteúdo principal

Núcleo FormatJS Intl

Tradução Beta Não Oficial

Esta página foi traduzida por PageTurner AI (beta). Não é oficialmente endossada pelo projeto. Encontrou um erro? Reportar problema →

Esta biblioteca contém a API intl essencial utilizada pelo react-intl.

Instalação

npm i -S @formatjs/intl

O objeto intl

O núcleo do @formatjs/intl é o objeto intl (do tipo IntlShape), que armazena em cache todas as APIs Intl.*, configurações, mensagens compiladas e afins. O ciclo de vida do objeto intl normalmente está vinculado ao locale e à lista de messages que contém, o que significa que ao alternar o locale, este objeto deve ser recriado.

dica

O objeto intl deve ser reutilizado sempre que possível por questões de desempenho.

createIntl

Permite criar um objeto IntlShape que contém todos os métodos format*. Por exemplo:

import {createIntl, createIntlCache} from '@formatjs/intl'

// This is optional but highly recommended
// since it prevents memory leak
const cache = createIntlCache()

const intl = createIntl(
{
locale: 'fr-FR',
messages: {},
},
cache
)

// Call imperatively
intl.formatNumber(20)

createIntlCache

Cria uma instância de cache para uso global entre locales. Memoriza construtores Intl.* previamente criados para desempenho, sendo apenas um cache em memória.

IntlShape

interface IntlConfig {
locale: string
timeZone?: string
fallbackOnEmptyString?: boolean
formats: CustomFormats
messages: Record<string, string> | Record<string, MessageFormatElement[]>
defaultLocale: string
defaultRichTextElements?: Record<string, FormatXMLElementFn<React.ReactNode>>
defaultFormats: CustomFormats
onError(err: string): void
onWarn(warning: string): void
}

interface IntlFormatters {
formatDate(value: number | Date | string, opts?: FormatDateOptions): string
formatTime(value: number | Date | string, opts?: FormatDateOptions): string
formatDateToParts(
value: number | Date | string,
opts?: FormatDateOptions
): Intl.DateTimeFormatPart[]
formatTimeToParts(
value: number | Date | string,
opts?: FormatDateOptions
): Intl.DateTimeFormatPart[]
formatRelativeTime(
value: number,
unit?: FormattableUnit,
opts?: FormatRelativeTimeOptions
): string
formatNumber(value: number, opts?: FormatNumberOptions): string
formatNumberToParts(
value: number,
opts?: FormatNumberOptions
): Intl.NumberFormatPart[]
formatPlural(
value: number | string,
opts?: FormatPluralOptions
): ReturnType<Intl.PluralRules['select']>
formatMessage(
descriptor: MessageDescriptor,
values?: Record<string, PrimitiveType | FormatXMLElementFn<string, string>>
): string
formatMessage(
descriptor: MessageDescriptor,
values?: Record<string, PrimitiveType | T | FormatXMLElementFn<T, R>>
): R
formatList(values: Iterable<string>, opts?: FormatListOptions): string
formatList(
values: Iterable<string | T>,
opts?: FormatListOptions
): T | string | Array<string | T>
formatListToParts(
values: Iterable<string | T>,
opts?: FormatListOptions
): Part[]
formatDisplayName(
value: string,
opts?: FormatDisplayNameOptions
): string | undefined
}

type IntlShape = IntlConfig & IntlFormatters

A definição acima mostra como será o objeto intl. Ele é composto por duas partes:

  • IntlConfig: Metadados intl passados como props no componente pai <IntlProvider>.

  • IntlFormatters: A API imperativa de formatação descrita abaixo.

locale, formats e messages

O locale atual do usuário e no qual o aplicativo deve ser renderizado. Enquanto defaultLocale e defaultFormats servem para fallbacks ou durante o desenvolvimento, representando os padrões do aplicativo. Note que não há defaultMessages, pois cada Message Descriptor fornece seu próprio defaultMessage.

defaultLocale e defaultFormats

Locale e formatos padrão para quando uma mensagem não está traduzida (ausente em messages). defaultLocale deve ser o locale onde defaultMessages são declarados, garantindo coerência na sentença. Sem defaultLocale ou configurado incorretamente, pode ocorrer uma sentença em inglês com data/hora em espanhol.

onError

Permite fornecer um tratador de erros personalizado. Por padrão, erros são registrados via console.error se NODE_ENV não estiver definido como production.

defaultRichTextElements

Um mapeamento de tags para funções de formatação de rich text. Fornece uma forma centralizada de formatar tags comuns como <b>, <p>... ou aplicar sistemas de design (ex: <a> ou <button> padronizados). Veja https://github.com/formatjs/formatjs/issues/1752 para contexto.

fallbackOnEmptyString

Padrão: true.

Esta opção booleana é útil para fornecer valores vazios intencionais em certos locales via strings vazias. Quando fallbackOnEmptyString é false, strings vazias são retornadas em vez de acionar o fallback. Este comportamento permite "omitir" conteúdo em locales específicos.

Veja esta issue para contexto.

formatDate

function formatDate(
value: number | Date,
options?: Intl.DateTimeFormatOptions & {format?: string}
): string

Retorna uma string formatada de data. Espera um value que possa ser interpretado como data (ex: isFinite(new Date(value))) e aceita options que seguem DateTimeFormatOptions.

Live Editor
intl.formatDate(Date.now(), {
  year: 'numeric',
  month: 'numeric',
  day: 'numeric',
})
Result

formatTime

function formatTime(
value: number | Date,
options?: Intl.DateTimeFormatOptions & {format?: string}
): string

Esta função retorna uma string formatada de data, mas difere do formatDate por ter as seguintes opções padrão:

{
hour: 'numeric',
minute: 'numeric',
}

Espera um value que possa ser interpretado como data (ex: isFinite(new Date(value))) e aceita options que seguem DateTimeFormatOptions.

Live Editor
intl.formatTime(Date.now()) // "4:03 PM"
Result

formatRelativeTime

suporte em navegadores

Isso requer Intl.RelativeTimeFormat, que possui suporte limitado em navegadores. Use nosso polyfill se precisar de compatibilidade.

type Unit =
| 'second'
| 'minute'
| 'hour'
| 'day'
| 'week'
| 'month'
| 'quarter'
| 'year'

type RelativeTimeFormatOptions = {
numeric?: 'always' | 'auto'
style?: 'long' | 'short' | 'narrow'
}

function formatRelativeTime(
value: number,
unit: Unit,
options?: Intl.RelativeTimeFormatOptions & {
format?: string
}
): string

Retorna uma string de tempo relativo formatado (ex: "há 1 hora"). Espera um value numérico, uma unit e options que seguem Intl.RelativeTimeFormatOptions.

Live Editor
intl.formatRelativeTime(0)
Result
Live Editor
intl.formatRelativeTime(-24, 'hour', {style: 'narrow'})
Result

formatNumber

Esta função utiliza opções de Intl.NumberFormat.

function formatNumber(
value: number,
options?: Intl.NumberFormatOptions & {format?: string}
): string

Retorna uma string numérica formatada. Espera um value interpretável como número e aceita options que seguem NumberFormatOptions.

Live Editor
intl.formatNumber(1000, {style: 'currency', currency: 'USD'})
Result

Formatação numérica usando unit

Atualmente parte do ES2020 NumberFormat. Disponibilizamos um polyfill aqui e os tipos do @formatjs/intl permitem passar uma unidade homologada:

Live Editor
intl.formatNumber(1000, {
  style: 'unit',
  unit: 'kilobyte',
  unitDisplay: 'narrow',
})
Result
Live Editor
intl.formatNumber(1000, {
  unit: 'fahrenheit',
  unitDisplay: 'long',
  style: 'unit',
})
Result

formatPlural

type PluralFormatOptions = {
type?: 'cardinal' | 'ordinal' = 'cardinal'
}

function formatPlural(
value: number,
options?: Intl.PluralFormatOptions
): 'zero' | 'one' | 'two' | 'few' | 'many' | 'other'

Retorna uma categoria plural: "zero", "one", "two", "few", "many" ou "other". Espera um value interpretável como número e aceita options que seguem PluralFormatOptions.

Utilitário de baixo nível cuja saída pode alimentar estruturas switch para selecionar strings específicas.

Live Editor
intl.formatPlural(1)
Result
Live Editor
intl.formatPlural(3, {style: 'ordinal'})
Result
Live Editor
intl.formatPlural(4, {style: 'ordinal'})
Result
suporte multilíngue

Use apenas em aplicações com suporte a um único idioma. Para múltiplos idiomas, prefira formatMessage.

formatList

suporte em navegadores

Isso requer Intl.ListFormat, que possui suporte limitado em navegadores. Use nosso polyfill se precisar de compatibilidade.

type ListFormatOptions = {
type?: 'disjunction' | 'conjunction' | 'unit'
style?: 'long' | 'short' | 'narrow'
}

function formatList(
elements: Iterable<string | React.ReactNode>,
options?: Intl.ListFormatOptions
): string | React.ReactNode[]

Esta função permite juntar listas de elementos de forma segura para internacionalização. Por exemplo, quando o locale é en:

Live Editor
intl.formatList(['Me', 'myself', 'I'], {type: 'conjunction'})
Result
Live Editor
intl.formatList(['5 hours', '3 minutes'], {type: 'unit'})
Result

formatDisplayName

suporte em navegadores

Isso requer Intl.DisplayNames, que possui suporte limitado em navegadores. Use nosso polyfill se precisar de compatibilidade.

type FormatDisplayNameOptions = {
style?: 'narrow' | 'short' | 'long'
type?: 'language' | 'region' | 'script' | 'currency'
fallback?: 'code' | 'none'
}

function formatDisplayName(
value: string | number | Record<string, unknown>,
options: FormatDisplayNameOptions
): string | undefined

Exemplos de uso:

Live Editor
intl.formatDisplayName('zh-Hans-SG', {type: 'language'})
Result
Live Editor
// ISO-15924 four letters script code to localized display name
intl.formatDisplayName('Deva', {type: 'script'})
Result
Live Editor
// ISO-4217 currency code to localized display name
intl.formatDisplayName('CNY', {type: 'currency'})
Result
Live Editor
// ISO-3166 two letters region code to localized display name
intl.formatDisplayName('UN', {type: 'region'})
Result

formatMessage

Sintaxe da Mensagem

A formatação de strings/mensagens é fundamental no React Intl, baseando-se na Formatação ICU através da Sintaxe de Mensagem ICU. Esta sintaxe permite definir mensagens simples ou complexas, traduzi-las e formatá-las em tempo de execução.

Mensagem Simples:

Hello, {name}

Mensagem Complexa:

Hello, {name}, you have {itemCount, plural,
=0 {no items}
one {# item}
other {# items}
}.

Veja: O Guia de Sintaxe de Mensagem.

Descritor de Mensagem

O React Intl usa o conceito de Message Descriptor para definir mensagens padrão do aplicativo, passadas para formatMessage. Esses descritores são fundamentais para traduções e contêm:

  • id: Identificador único e estável para a mensagem

  • description: Contexto para tradutores sobre o uso na interface

  • defaultMessage: Mensagem padrão (geralmente em inglês)

type MessageDescriptor = {
id: string
defaultMessage?: string
description?: string | object
}
Extração de Message Descriptor

Você pode extrair mensagens declaradas inline de arquivos fonte usando nossa CLI.

Fallbacks de Formatação de Mensagem

As APIs de formatação implementam fallbacks robustos para garantir retorno de strings não vazias. O algoritmo é:

  1. Busca e formata mensagem traduzida pelo id no <IntlProvider>

  2. Fallback para formatação do defaultMessage.

  3. Fallback para fonte da mensagem traduzida pelo id

  4. Fallback para fonte do defaultMessage

  5. Fallback para o id literal da mensagem.

"Fonte" refere-se ao uso do template bruto, sem substituições.

Uso

type MessageFormatPrimitiveValue = string | number | boolean | null | undefined
function formatMessage(
descriptor: MessageDescriptor,
values?: Record<string, MessageFormatPrimitiveValue>
): string
function formatMessage(
descriptor: MessageDescriptor,
values?: Record<
string,
MessageFormatPrimitiveValue | React.ReactElement | FormatXMLElementFn
>
): string | React.ReactNode[]

Esta função retorna uma string de mensagem formatada. Espera um MessageDescriptor com pelo menos a propriedade id e aceita um objeto values para preencher placeholders.

Se uma mensagem traduzida com esse id foi passada ao <IntlProvider> via prop messages, ela será formatada. Caso contrário, usa fallback para defaultMessage. Veja Fallbacks de Formatação.

Live Editor
function () {
  const messages = defineMessages({
    greeting: {
      id: 'app.greeting',
      defaultMessage: 'Hello, {name}!',
      description: 'Greeting to welcome the user to the app',
    },
  })

  return intl.formatMessage(messages.greeting, {name: 'Eric'})
}
Result

com ReactElement

Live Editor
function () {
  const messages = defineMessages({
    greeting: {
      id: 'app.greeting',
      defaultMessage: 'Hello, {name}!',
      description: 'Greeting to welcome the user to the app',
    },
  })

  return intl.formatMessage(messages.greeting, {name: <b>Eric</b>})
}
Result

com formatação rich text

Live Editor
function () {
  const messages = defineMessages({
    greeting: {
      id: 'app.greeting',
      defaultMessage: 'Hello, <bold>{name}</bold>!',
      description: 'Greeting to welcome the user to the app',
    },
  })

  return intl.formatMessage(messages.greeting, {
    name: 'Eric',
    bold: str => <b>{str}</b>,
  })
}
Result

A mensagem definida usando defineMessages para extração via babel-plugin-formatjs, mas não é obrigatório sem o plugin Babel.

mensagem simples

Mensagens podem ser strings simples sem placeholders, sendo o tipo mais comum.

defineMessages/defineMessage

interface MessageDescriptor {
id?: string
description?: string | object
defaultMessage?: string
}

function defineMessages(
messageDescriptors: Record<string, MessageDescriptor>
): Record<string, MessageDescriptor>

function defineMessage(messageDescriptor: MessageDescriptor): MessageDescriptor

Exportadas por @formatjs/intl, funcionam como hook para CLI e plugins babel/TS compilarem mensagens padrão em arquivos JavaScript. Simplesmente retornam o objeto Message Descriptor fornecido.

import {defineMessages, defineMessage} from '@formatjs/intl'

const messages = defineMessages({
greeting: {
id: 'app.home.greeting',
description: 'Message to greet the user.',
defaultMessage: 'Hello, {name}!',
},
})

const msg = defineMessage({
id: 'single',
defaultMessage: 'single message',
description: 'header',
})