O que é i18n?
A internacionalização (i18n) é o processo de criação de software para que ele possa ser adaptado a diferentes idiomas e regiões sem alterar seu código. O apelido “i18n” vem do fato de haver 18 letras entre o “i” e o “n” na internacionalização.
Pense no i18n como uma base para:
- Localização (l10n): traduzir e adaptar seu conteúdo para um mercado específico.
- Globalização (g11n): Coordenar a prontidão e as operações do produto em todos os mercados.
Na prática, o i18n trata de garantir que seu aplicativo possa lidar com:
- Texto em qualquer idioma
- Datas, horas, números e moedas no formato certo
- Regras de pluralização que correspondem à gramática local
- Layouts da direita para a esquerda (como árabe ou hebraico)
Por que o i18n é importante
Investir antecipadamente no i18n traz benefícios tangíveis para suas equipes de engenharia e produto:
- Custos de localização mais baixos: extrair e substituir cadeias de caracteres é mais fácil quando a lógica de tradução é incorporada desde o início.
- Desenvolvimento mais rápido: a infraestrutura compartilhada para gerenciar strings reduz o retrabalho futuro.
- Melhor experiência do usuário: os usuários veem o conteúdo em seu idioma, formatado de uma forma que pareça natural.
- Escalabilidade: os aplicativos podem ser lançados em novos mercados com menos alterações de código.
padrões de implementação do i18n em aplicativos modernos
Abaixo estão alguns padrões comuns para implementar o i18n em aplicativos de nível de produção. Examinaremos React (frontend), iOS e Android.
Não importa a plataforma, as traduções geralmente vêm de um sistema de gerenciamento de tradução (TMS) como o Smartling como JSON ou arquivos de recursos. Esses arquivos são então carregados pelo seu aplicativo em tempo de execução por meio de uma estrutura i18n ou API de localização nativa, garantindo que as sequências de caracteres corretas sejam exibidas para o idioma ou localidade do usuário.
Interface (React)
Os aplicativos React modernos normalmente usam uma biblioteca i18n dedicada. Dois dos mais populares são o i18next e o FormatJS, ambos independentes de estrutura. No React, suas respectivas implementações são react-i18next (baseado em função e gancho) e react-intl (baseado em componentes e ganchos, construído no ICU MessageFormat). Ambos se integram de forma limpa aos pipelines corporativos e lidam com pluralização, variáveis e formatação com reconhecimento de localidade.
1. Reaja com i18next + react-i18next
A i18next é uma das bibliotecas i18n de JavaScript mais populares e, quando combinada com as ligações react-i18next, fornece aos aplicativos React uma API poderosa e fácil de usar para carregar e renderizar traduções.
No exemplo abaixo, abordaremos um padrão corporativo i18n comum. Definiremos os arquivos de tradução, inicializaremos o i18next no ponto de entrada do aplicativo e, em seguida, renderizaremos as traduções em componentes. Essa abordagem funciona em todas as estruturas, se integra perfeitamente à maioria dos sistemas de gerenciamento de tradução (TMS) e se adapta à medida que seu aplicativo cresce, independentemente de você estar exibindo cadeias de caracteres estáticas ou mensagens dinâmicas e orientadas por variáveis, como contagens.
Exemplo de padrão i18n: i18next + reacti18next
Você provavelmente receberá conteúdo como arquivos JSON do seu sistema de gerenciamento de tradução. O exemplo de arquivo JSON abaixo mostra como as traduções são armazenadas para o inglês. Cada entrada tem uma chave exclusiva, e as formas plurais são definidas separadamente para que a biblioteca possa escolher a correta com base na contagem aprovada. Seu TMS gerará um arquivo correspondente para cada idioma suportado.
{
"welcome": "Welcome",
" visits_one ": " Você visitou {{count}} uma vez. ",
" visits_other ": " Você já visitou {{count}} vezes. "
}
A seguir, você verá um exemplo de como configurar o i18next para que ele saiba quais idiomas seu aplicativo suporta, onde encontrar as traduções e o que fazer se uma tradução estiver ausente. Esse arquivo de configuração é executado uma vez quando o aplicativo é iniciado (geralmente no arquivo do ponto de entrada, como index.js ou main.tsx) para que as traduções estejam prontas antes de qualquer interface de usuário ser renderizada. Centralizar a configuração em um só lugar mantém sua lógica de localização consistente em todo o seu aplicativo.
importar i18next de 'i18next';
importar {initReacti18Next} de 'react-i18next';
import en from './locales/en/translation.json';
importar fr de '. /locales/pt-BR/translation.json ';
const locale = 'fr';//na produção, resolva dinamicamente
i18next
.use(initReactI18next)
.init({
lng: locale,
fallbackLng: 'en',
recursos: {
en: { translation: en },
fr: {tradução: fr}
},
interpolação: {escapeValue: false}
});
exportar i18next padrão;
Depois que o i18next for inicializado, você poderá usá-lo em qualquer lugar do seu aplicativo. No exemplo abaixo, o gancho useTranslation recupera a função t, que usa uma chave e variáveis opcionais para renderizar a string correta. Quando você passa count como uma variável, o i18next seleciona automaticamente a forma plural correta com base no arquivo de tradução.
importar {useTranslation} de 'react-i18next';
import './i18n';
função padrão de exportação App () {
const {t} = useTranslation ();
contagem constante = 3;
retornar (
< >
<h1>{t('welcome')}</h1>
<p>{t ('visitas', {contagem})}</p>
</>
);
}
2. Reaja com FormatJS + react-intl
react-intl faz parte do ecossistema FormatJS e fornece uma abordagem baseada em componentes para i18n no React. Ele é baseado no padrão ICU MessageFormat, para que você obtenha pluralização integrada, formatação de data/número e fallback de localidade.
No exemplo abaixo, vamos configurar arquivos de tradução, agrupar o aplicativo em um IntlProvider e renderizar texto localizado usando FormattedMessage. Essa abordagem é adequada para equipes que desejam um estilo declarativo e orientado por componentes para lidar com i18n no React.
Exemplo de padrão i18n: formatJS + react-intl
O arquivo JSON abaixo contém traduções usando a sintaxe ICU MessageFormat, que coloca a lógica plural dentro da própria string. Isso mantém todas as regras do idioma em um só lugar e permite que os tradutores controlem totalmente a gramática sem a intervenção do desenvolvedor. Seu TMS gerencia esses arquivos por localidade.
{
"welcome": "Welcome",
{% raw%} " visita ": " Você visitou {count, plural, uma {# vez} e outras {# vezes}}. " {% end_raw%}A seguir, você verá um exemplo de como agrupar seu aplicativo no componente IntlProvider. Essa é uma configuração única, geralmente feita em um componente raiz, como root.tsx ou index.jsx. Ele disponibiliza a localidade ativa e suas mensagens em todo o aplicativo para que qualquer componente possa usá-las sem importações extras.
importar {IntlProvider} de 'react-intl';
import en from './locales/en.json';
importar fr de '. /locales/pt-BR.json ';
const MESSAGES = { en, fr };
const locale = 'fr';
função padrão de exportação Root () {
retornar (
<IntlProvider locale={locale} messages={MESSAGES[locale]}>
<App />
</IntlProvider>
);
}
Por fim, leia abaixo para ver como o componente FormattedMessage procura uma tradução por seu ID e lida com a pluralização automaticamente. Tudo o que você precisa passar é a contagem, e a biblioteca aplica as regras de linguagem corretas do seu arquivo JSON.
importar {formattedMessage} de 'react-intl';
função padrão de exportação App () {
contagem constante = 3;
retornar (
< >
<h1><FormattedMessage id="welcome" defaultMessage="Welcome" /></h1>
<p><FormattedMessage id="visits" values={{ count }} /></p>
</>
);
}
Algumas dicas adicionais para uso em produção:
- Origem da localidade: Em aplicativos reais, determine a localidade centralmente (por exemplo, a partir de uma URL como /fr/*, do perfil do usuário ou de uma configuração fornecida pelo servidor) e passe-a para <IntlProvider>.
- Organização de mensagens: para escalar, divida os arquivos de mensagens por domínio ou recurso (por exemplo, auth.json, dashboard.json) e mescle-os para o local ativo.
- Substitutos: DefaultMessage é sua rede de segurança durante o lançamento — mantenha-a em seu idioma de origem.
- Carregamento assíncrono (opcional): para pacotes grandes, importe dinamicamente os arquivos de mensagens por localidade (divisão de código) antes de renderizar<IntlProvider>.
iOS
O iOS oferece ferramentas de localização sólidas prontas para uso, mas uma escalabilidade limpa para muitos locais exige uma implementação cuidadosa das melhores práticas do i18n. Caso contrário, sem uma estrutura clara, você pode acabar com chaves duplicadas, formatação inconsistente e arquivos de tradução que se tornam uma dor de cabeça para manter. A chave é tomar algumas decisões estruturais com antecedência, para que sua localização permaneça organizada e fácil de ampliar à medida que novos mercados são adicionados.
Dica 1: organize os recursos de uma forma escalável
Um bom lugar para começar é com String Catalogs (.xcstrings) no Xcode 15 e posterior, ou .strings/.stringsdict arquivos se você estiver em uma configuração mais antiga. Eles funcionam bem com um TMS, que geralmente envia traduções no formato XLIFF. Você pode importá-los diretamente para o seu catálogo, e o sistema cuidará do trabalho pesado de mesclá-los e gerenciá-los.
Você provavelmente achará mais fácil manter as coisas organizadas se organizar os catálogos por recurso ou módulo. Arquivos menores e direcionados facilitam a localização de chaves, a revisão de alterações e a entrega do trabalho aos tradutores. Aqui está um exemplo de como você pode querer organizá-los:
Recursos
i18n/
Auth.xcstrings
Confira as strings.xc
Profile.xcstrings
Dica 2: lidar com a pluralização no catálogo, não no código
A pluralização é outro lugar em que a estrutura compensa. É melhor definir todas as regras plurais no catálogo em vez de no Swift, para que seu código apenas passe variáveis e a frase certa seja escolhida automaticamente para cada idioma. Veja o que isso pode parecer no catálogo:
Chave: unread_messages
Formato: Plural
Um: " %d mensagem não lida "
Outras: " %d mensagens não lidas "
E veja como você pode usá-lo no Swift:
deixe UnreadCount = 3
let format = String (localizado: " unread_messages ")
let message = string.localizedStringWithFormat (format, Contagem não lida)
//" 3 mensagens não lidas "
Dessa forma, você não está codificando gramática em código, e os tradutores podem obter os detalhes corretos para cada idioma.
Dica 3: centralize a formatação de números, datas e moedas
Você também deve centralizar a formatação de números, datas e moedas para que cada parte do aplicativo pareça consistente. Um utilitário ou serviço compartilhado pode ajudar com isso. Aqui está um exemplo simples usando a moderna API FormatStyle do Swift:
preço do aluguel = 19,99
let display = price.formatted (.currency) (código: " EUR ")
//" 19,99€ " ou " 19,99€ " dependendo da localidade
Ao manter seus recursos de string organizados, lidar com a pluralização no catálogo e centralizar toda a formatação com reconhecimento de localidade, você configura seu aplicativo iOS para crescer sem criar trabalho extra de manutenção. Uma vez implementadas essas práticas, o processo de adição de novos idiomas se torna muito mais previsível — e muito menos estressante. Agora vamos dar uma olhada no Android, que oferece suas próprias ferramentas de localização integradas.
Android
O sistema de recursos do Android já foi projetado com a localização em mente, mas mantê-lo sustentável em vários idiomas exige algum planejamento. Se você mantiver tudo em um arquivo grande ou dispersar as regras gramaticais no código, tudo pode ficar confuso rapidamente. Em vez disso, priorize a organização segmentada de arquivos, defina todas as regras gramaticais em XML e garanta que a formatação e os layouts funcionem em todos os sistemas de escrita que você planeja oferecer suporte.
Dica 1: mantenha os recursos organizados por recurso
Para a maioria das equipes, as traduções virão de um TMS como arquivos XLIFF. Você os importa para os diretórios res/values de cada localidade, e o Android se encarrega de combinar as strings corretas com o idioma do usuário.
Dividir seus recursos em arquivos separados por recurso é uma maneira simples de facilitar a vida. Arquivos menores agilizam a revisão das alterações e ajudam a evitar conflitos de mesclagem.
app/src/main/res/
values/strings_auth.xml
values/strings_checkout.xml
values/plurals_checkout.xml
Dica 2: defina regras gramaticais em recursos, não em código
Assim como no iOS, a pluralização é uma das coisas mais bem tratadas em recursos para que os tradutores possam adaptá-la por idioma sem que você altere o código. Aqui está um exemplo de um recurso plural em inglês:
<plurals name="checkout_cart_items_count">
<item quantity="one">%1$d item</item>
< quantidade de itens = " outros itens " > %1$d</item>
</plurals>
E veja como você o usaria em Kotlin:
val msg = recursos.getQuantityString (
r.plurals.checkout_cart_items_count, contar, contar
)
Dessa forma, nosso código permanece limpo e o Android escolhe automaticamente a forma correta com base na localidade.
Dica 3: use a formatação com reconhecimento de localidade
Para layouts, é um bom hábito usar início e fim em vez de esquerda e direita para que eles se adaptem a idiomas da direita para a esquerda, como árabe ou hebraico:
<LinearLayout
android:paddingStart="16dp"
android:paddingEnd="16dp"
android:layout_width="match_parent"
android:layout_height="wrap_content">
</LinearLayout>
E ao formatar números ou moedas, passe a localidade atual do aplicativo para que tudo pareça consistente:
val appLocale = LocaleListCompat.getAdjustedDefault()[0] ?: Locale.getDefault()
val price = numberFormat.getCurrencyInstance (AppLocale) .format (1234,56)
//" $1.234,56 " ou " 1 234,56€ "
No final das contas, acertar o Android i18n significa principalmente deixar a plataforma fazer o trabalho pesado. Ao manter todo o texto nos recursos, estruturar esses recursos com pastas específicas do local e criar formatação RTL e com reconhecimento de local desde o primeiro dia, você evita as armadilhas comuns que tornam a localização frágil. Muitos desses princípios refletem as melhores práticas do iOS, mas o sistema qualificador de recursos do Android significa que você geralmente pode oferecer suporte a novos idiomas simplesmente adicionando os arquivos certos. Bem feito, o dimensionamento para novos locais se torna um processo previsível e de baixo esforço.
Armadilhas comuns do i18n
Infelizmente, até mesmo sistemas bem construídos às vezes enfrentam problemas evitáveis. A tabela abaixo mostra alguns dos erros mais comuns, por que eles causam problemas e como evitá-los. Considere isso uma referência rápida que você pode usar para verificar sua própria configuração antes do envio.
Erro |
Como evitá-lo |
Cordas codificadas |
Extraia todo o texto voltado para o usuário em arquivos de recursos ou chaves de tradução. |
Supondo que todo o texto seja da esquerda para a direita |
Teste layouts com idiomas da direita para a esquerda, como árabe ou hebraico. |
Negligenciando a pluralização |
Use bibliotecas que suportem regras plurais (por exemplo, formato ICU, i18next). |
Unidades ou formatos não localizados |
Use formatação com reconhecimento de localidade (por exemplo, Intl.NumberFormat, Intl.DateTimeFormat). |
Ignorando verificações de expansão de texto |
Teste com pseudo-localidades para simular traduções mais longas. |
Extração incompleta de strings |
Use pseudo-localidades na preparação para revelar strings ausentes ou não marcadas. |
Preparação para a localização em grande escala
Depois que seu aplicativo estiver configurado para internacionalização, a próxima etapa é tornar a localização o mais eficiente e de baixa manutenção possível. Algumas ferramentas de automação e fluxos de trabalho podem levar você de “podemos traduzir” para “podemos lançar novos idiomas rapidamente, sem carga extra de desenvolvimento”. Considere:
- Usando um Sistema de Gerenciamento de Tradução (TMS) com uma API de nível empresarial, como o Smartling, para sincronizar arquivos de tradução e gerenciar fluxos de trabalho de revisão.
- Automatizando a extração e entrega de strings usando seu pipeline de CI/CD.
- Usando ferramentas de IA (como o AI Hub da Smartling) para traduções rápidas de primeira passagem com verificações de qualidade integradas, como tratamento de fallbacks e mitigação de alucinações.
Considerações finais
A internacionalização é uma prática fundamental para qualquer produto que se torna global e, quanto mais cedo você implementá-la, menos dores de cabeça terá mais tarde. Combine práticas sólidas de i18n com automação de tradução e fluxos de trabalho de teste, e sua equipe estará bem equipada para enviar software pronto para uso internacional com mais rapidez e confiança.
Quer ir mais fundo? Confira o Smartling's Webinar da Global Ready Conference sobre i18n estratégia na era da IA.