Conforme a globalização aumenta, escrever aplicativos React para um público amplo em diferentes regiões e localidades significa torná-lo acessível em todos os idiomas.

Com recursos de internacionalização, a biblioteca React Intl fornece o mecanismo para traduzir adequadamente o texto do arquivo para outros idiomas.

Neste guia, aprenderemos como usar a biblioteca React Intl para configurar a internacionalização em um projeto React. Criaremos um aplicativo simples que permite aos usuários selecionar e ver o idioma de sua preferência ao visualizá-lo.

Também manteremos o local selecionado no armazenamento do navegador para que o conteúdo ainda esteja disponível após uma atualização da página ou em uma visita subsequente.

Abaixo está o produto final do que construiremos juntos:

React Intl End Produto

Interaja com a página da web finalizada para se familiarizar com a interface e, com isso, vamos começar!

Internacionalização e localização

Conforme mencionado anteriormente, o React Intl nos permite definir internacionalização em um aplicativo React . Mas o que exatamente é internacionalização?

Internacionalização é o processo de criação de um produto-neste caso, um aplicativo React-para ser usado em diferentes locais. Geralmente é abreviado como Intl ou i18n.

Em contraste, a localização, abreviada como l10n, se concentra na tradução de um aplicativo internacionalizado de seu idioma original para um idioma específico.

Mas hey, tradução é mais do que apenas transformar o texto ou mensagem para um idioma de destino. As diferenças culturais também devem ser consideradas, como a forma como os números e as datas são escritos ou como as unidades e moedas são colocadas para diferentes locais.

Felizmente, com a biblioteca React Intl, podemos alcançar o resultado desejado perfeitamente.

Configurando o projeto React

Vamos começar obtendo nosso projeto React simples-com seu conteúdo padrão em inglês-de este repositório GitHub . Em seguida, podemos adicionar suporte para três idiomas adicionais: francês, alemão e japonês.

Então, vá para o terminal, mude para um diretório para salvar o projeto e execute o seguinte comando para baixar os arquivos iniciais:

 clone git https://github.com/Ibaslogic/i18n_react_intl_starter

Depois de inicializar os arquivos do projeto, abra-os com um editor de código. Devemos estar dentro do diretório do projeto e executar npm install para criar uma pasta node_modules para o projeto.

Certifique-se de que o Node.js esteja instalado no computador para concluir este tutorial.

Agora, inicie o servidor de desenvolvimento usando npm start . Devemos ver nosso aplicativo carregado no navegador em http://localhost: 3000 .

Aplicativo carregado no navegador

Se dermos uma olhada na estrutura de arquivos do projeto, devemos ter o seguinte:

 pasta_projeto ├── node_modules ├── público ├── src │ ├── componentes │ │ ├── App.js │ │ ├── Content.js │ │ ├── Footer.js │ │ └── Header.js │ ├── index.css │ └── index.js ├──.gitignore ├── package-lock.json ├── package.json ├── README.md └── yarn.lock

Ótimo. Agora que estamos na mesma página, vamos ver como podemos usar a biblioteca React Intl em nosso aplicativo.

Configurando a biblioteca React Intl

Para usar esta biblioteca, devemos instalá-la parando o servidor de desenvolvimento e executando o seguinte comando no terminal:

 npm install react-intl

Essa biblioteca nos fornece todas as APIs e componentes necessários para implementar a internacionalização em nosso aplicativo.

Vamos envolver o aplicativo de nível superior ou o componente raiz de nosso aplicativo em um componente provedor da biblioteca; neste caso, usaremos .

O que é o componente IntlProvider ?

Como o nome indica, IntlProvider garante que configurações importantes sejam fornecidas ou disponibilizadas para os subcomponentes na árvore.

Esses subcomponentes do React Intl são chamados de componentes formatados . Eles são responsáveis ​​pela tradução e formatação adequadas em tempo de execução. Esses componentes são:

  • FormattedMessage
  • FormattedNumber
  • FormattedDate
  • FormattedPlural
  • E muitos mais

Para projetos de internacionalização usando a biblioteca React Intl, o componente FormattedMessage é freqüentemente usado, permitindo aos usuários traduzir e formatar strings e mensagens simples para complexas. Estaremos usando isso em um momento.

De volta ao nosso projeto, vamos abrir o arquivo do componente pai src/components/App.js e envolver os componentes filhos com IntlProvider .

Certifique-se de importar IntlProvider de react-intl na parte superior do arquivo.

Nosso arquivo deve ser semelhante a este:

...
import {IntlProvider} de"react-intl"; const App=()=> { Retorna (  
); }; exportar aplicativo padrão;

Vamos verificar o que o componente IntlProvider retorna. Primeiro, registre o componente:

...
const App=()=> { console.log (IntlProvider); Retorna ( ... );
};
...

Em seguida, verifique o console do navegador:

Props de configuração padrão

Focando no defaultProps , vemos todos os props de configuração padrão usados ​​por IntlProvider . O componente também está nos dizendo para configurar uma localidade.

Então, vamos adicionar os adereços necessários para identificar e exibir traduções para IntlProvider atualizando o componente para incluir os seguintes adereços:

 return (  
);

Imediatamente adicionando o prop locale e salvando, o erro desaparece.

Este locale , que aceita uma string, determina em qual idioma nosso aplicativo é renderizado. Vamos adicionar dinamicamente o valor com base no que os usuários selecionarem no front-end.

O objeto messages contém um conjunto de strings traduzidas prontas para serem exibidas no frontend. Eles também serão adicionados dinamicamente com base na localidade atual.

Por último, a prop defaultLocale é a localidade padrão e deve corresponder ao idioma padrão do aplicativo.

Antes de carregarmos as mensagens traduzidas para nosso projeto, vamos brincar e nos familiarizar com os componentes formatados.

Abra o arquivo src/components/Footer.js e adicione esses componentes formatados na instrução return :

//...
import {FormattedDate, FormattedNumber, FormattedPlural} de"react-intl"; const Footer=()=> { //... Retorna ( 
{/*... */}

); }; //...

A seguir, salve o arquivo e verifique o frontend. Devemos ter isso exibido:

 29/05/2021//sua data atual
2.000
5 cliques

Se alterarmos o prop locale do IntlProvider para de e salvarmos o arquivo mais uma vez, teremos os dados formatados em alemão:

 29.5.2021 2.000

Isso é incrível. React Intl está formatando a data e o número com base na região selecionada por meio dos componentes formatados ( FormattedDate e FormattedNumber , respectivamente).

Esses componentes formatados têm um prop valor que aceita os dados a serem formatados.

Podemos personalizar ainda mais esses componentes tirando proveito de seus outros adereços. Por exemplo, podemos ter o seguinte:

 return ( 
{/*... */}

{/*... */}
);

Então, obteremos isso para o inglês ( en ):

 29 de maio de 2021//sua data atual $ 2.000,00

E então obteremos isto para alemão ( de ):

 29. Maio de 2021 2.000,00 $

Além desses dois componentes, também temos o componente FormattedPlural que nos permite lidar com plurais em nosso aplicativo. Conforme visto no exemplo acima, o componente seleciona uma categoria no plural com base no valor recebido.

Usando a API React Intl

Outra maneira de formatar nossos dados é por meio da API React Intl . Embora o uso do método de componente seja preferido no React porque funciona perfeitamente com outros componentes React, há casos onde o método da API é necessário, como quando o placeholder , title ou aria-label de um elemento deve ser traduzido.

Sempre que usamos componentes formatados para renderizar um elemento React, eles usam a API React Intl nos bastidores.

Vamos ver como essa API funciona. Ainda no arquivo Footer.js , importe o gancho useIntl de react-intl :

 import {FormattedDate, FormattedNumber, FormattedPlural, useIntl} de"react-intl";

Certifique-se de que isso seja feito em um componente React funcional.

Se registrarmos o gancho useIntl no console, devemos ver todas as funções disponíveis necessárias para formatar nossos dados:

//...
const Footer=()=> { //... const intl=useIntl (); console.log (intl); Retorna ( 
{/*... */}
); }; //... >

Uma dessas funções é formatDate ; vamos aplicá-lo.

Atualize a instrução return no arquivo Footer.js para incluir a função:

//...
const Footer=()=> { //... const intl=useIntl (); Retorna ( 
{/* <... */}
); }; //...

Verifique o frontend para ver o campo de entrada. Lembre-se de alterar o valor locale do IntlProvider para ver como funciona.

Podemos personalizar ainda mais adicionando a configuração opcional:

 

Agora que estamos familiarizados com esses formatadores, vamos voltar ao nosso projeto.

Traduzindo a string de texto de origem do aplicativo

Para suportar outras localidades, devemos traduzir o texto fonte. Para este tutorial, vamos usar o Google Tradutor .

Crie uma pasta chamada i18n no diretório src . Nesta pasta, crie dois arquivos diferentes chamados locales.js e messages.js . O arquivo locales.js conterá nossos locais suportados, enquanto o arquivo messages.js conterá as traduções correspondentes.

Adicione isso ao arquivo i18n/locales.js :

 export const LOCALES={ INGLÊS:"en-US", JAPONÊS:"ja-JA", FRANCÊS:"fr-FR", ALEMÃO:"de-DE",
};

Isso é necessário para evitar adicionar manualmente as localidades. Para acessar en-US , por exemplo, usaremos [LOCALES.ENGLISH] .

De onde vem o código?

O código en-US vem do código language-COUNTRY , embora também possamos usar apenas o idioma código sem adicionar o código código do PAÍS .

No entanto, em casos em que vários países têm o mesmo idioma, pode ser útil adicionar o esclarecedor PAÍS . Por exemplo, inglês nos Estados Unidos seria en-US e inglês no Reino Unido seria en-GB .

Traduções em React

Agora, no arquivo i18n/messages.js , adicione as seguintes traduções:

 importar {LOCALES} de"./locales"; export const messages={ [LOCALES.ENGLISH]: { learn_to:"Olá, vamos aprender como usar o React-Intl", price_display: "Como {n, número,:: moeda/USD} é exibido no idioma selecionado", number_display: "É assim que {n, número} é formatado no local selecionado", start_today:"Comece hoje: {d, data}", //cardápio about_project:"Sobre o projeto", contact_us:"Contate-nos", }, [LOCALES.FRENCH]: { learn_to:"Bonjour, apprenons à utiliser React-Intl", price_display: "Comentário {n, número,:: moeda/USD} $ s'affiche dans la langue sélectionnée", number_display: "Voici comment {n, number} sont formatés dans les paramètres régionaux sélectionnés", start_today:"Commencez aujourd'hui: {d, data}", //cardápio about_project:"À propos du projet", contact_us:"Contactez-nous", }, [LOCALES.GERMAN]: { learn_to:"Hallo, lass uns lernen, wie man React-Intl benutzt", price_display: "Wie {n, número,:: moeda/USD} em Ihrer ausgewählten Sprache angezeigt wird", number_display: "Auf diese Weise werden {n, número} im ausgewählten Gebietsschema formatiert", start_today:"Beginnen Sie heute: {d, date}", //cardápio about_project:"Über das Projekt", contact_us:"Kontaktiere uns", }, [LOCALES.JAPANESE]: { learn_to:"こ ん に ち は 、 React-Intl の 使 い 方 を 学 び び ま ょ う", price_display: "選 択 し た 言語 で {n, número,:: moeda/USD} が ど の よ う に に 表示 さ れ る か", number_display: "こ れ は 、 選 択 し た ロ ケ ー ル で {n, número} が フ ォ ー マ ッ ト さ れ る 方法 で す。", start_today:"今日 か ら 始 め る : {d, data}", //cardápio about_project:"プ ロ ジ ェ ク ト に つ い て", contact_us:"お 問 い 合 わ せ", },
};

Este arquivo contém o texto fonte do nosso aplicativo e as traduções para os locais suportados. Observe cada um dos IDs e chaves exclusivos, que podem ter qualquer nome; nós os usaremos para injetar suas strings correspondentes em nosso aplicativo.

Por enquanto, vamos nos concentrar nas strings simples e ignorar os argumentos, também conhecidos como marcadores, nas chaves.

A seguir, vamos carregar os dados na propriedade mensagem do componente IntlProvider .

Como podemos ver nos dados, podemos acessar o objeto de tradução em inglês da seguinte forma:

 mensagens [LOCALES.ENGLISH]

O mesmo se aplica a outras localidades.

Então, vamos atribuir esta tradução em inglês à propriedade messages do componente provedor . Posteriormente neste guia, definiremos uma lógica que injeta dinamicamente mensagens traduzidas com base na localidade selecionada pelo usuário.

No arquivo components/App.js , importe as LOCALES e as mensagens na parte superior do arquivo:

 importar {LOCALES} de"../i18n/locales";
importar {mensagens} de"../i18n/messages";

Então, atualize o para termos o seguinte:

 const App=()=> { const locale=LOCALES.ENGLISH; Retorna (  ...  );
}; exportar aplicativo padrão;

A partir do código, podemos deduzir que os dados em inglês são carregados no componente provedor e podem ser acessados ​​por meio do subcomponente.

Conforme mencionado anteriormente, usaremos FormattedMessage para formatar essas strings complexas. Este componente é ideal se nossa mensagem combina datas, números ou apenas mensagens simples.

Começaremos transformando a string simples, “Olá, vamos aprender a usar React-Intl.”

Vá até o arquivo components/Content.js e importe a FormattedMessage :

 import {FormattedMessage} de"react-intl";

Em seguida, substitua a string pelo componente:

 import {FormattedMessage} de"react-intl"; Const Content=()=> { Retorna ( 

{/*... */}
); }; exportar Conteúdo padrão;

É simples assim. Para testar nosso trabalho, podemos alterar manualmente o locale no arquivo App.js para JAPANESE :

 const locale=LOCALES.JAPANESE;

Salve e veja as mudanças no frontend:

Retornar a chave correspondente ao local atual

O FormattedMessage usado no código acima pega um prop id cujo valor corresponde a uma chave específica no arquivo de tradução e então retorna a string correspondente para o local atual. Lembre-se de que este id é único em todos os locais com suporte no arquivo de tradução.

Usando argumentos

Quando vemos uma mensagem que inclui uma data, valor ou número, queremos substituí-los por argumentos.

Anteriormente, aprendemos como formatar esses tipos de valores usando FormattedDate e FormattedNumber . Mas aqui usaremos a FormattedMessage , pois os valores são parte de uma string.

Se dermos uma olhada no arquivo de tradução, estaremos substituindo esses tipos de valor seguindo este padrão: {chave, tipo, formato} .

Por exemplo, temos algo assim:

 price_display: "Como {n, número,:: moeda/USD} é exibido no idioma selecionado",

O primeiro elemento, n , é a chave e consulta o objeto de dados para encontrar os dados apropriados. O segundo elemento é o tipo de dados a interpretar e está em conformidade com uma localidade específica.

O terceiro argumento-que é opcional-nos permite especificar informações adicionais sobre o tipo de elemento.

No caso acima, estamos dizendo que o marcador de posição do número deve ser formatado como moeda USD. Em seguida, o React Intl posiciona a moeda. Você pode encontrar a lista de códigos de moeda aqui .

Para transformar esse tipo de string usando a FormattedMessage , teremos algo assim:

 

Como esperado, o id localiza a tradução para o local atual, e o espaço reservado é substituído pelo valor de chave .

Se aplicarmos essa lógica em nosso projeto, o arquivo components/Content.js ficará assim:

 import {FormattedMessage} de"react-intl"; Const Content=()=> { Retorna ( 

); }; exportar Conteúdo padrão;

Salve o arquivo e teste o aplicativo alterando a localidade no arquivo component/App.js para outro idioma compatível:

 const locale=LOCALES.JAPANESE;

Nosso aplicativo deve ser semelhante a este:

Alterar o local Para outro idioma

Pluralização com React Intl

Anteriormente, aprendemos como usar o componente para lidar com um texto plural simples. Nesta seção, usaremos para obter plurais em uma mensagem rica em texto.

Atualmente, se clicarmos no botão de contagem no frontend, não temos lógica que exibe o texto correto quando a contagem está no singular, ou seja, quando está em 1 .

Quando formatamos a moeda usando o padrão {key, type, format} , podemos usar o mesmo padrão, mas usar plural e correspondências para substituir type e format , respectivamente.

Ao aplicar este padrão, podemos adicionar o seguinte ao nosso objeto de tradução em inglês:

 click_count:"Você clicou em {count, plural, one {# time} other {# times}}"

As categorias de plural, um e outro , correspondem às formas singular e plural dentro da primeira e segunda chaves, precedidas por # , que representa o número de contagem.

Se traduzirmos a mensagem para outras localidades e aplicarmos a mesma lógica, teremos o seguinte para o alemão:

 click_count: "Sie haben {count, plural, one {# Mal} other {# Mal}} geklickt",

Para francês:

 click_count: "Vous avez cliqué {contagem, plural, um {# fois} outro {# fois}}",

Para japonês:

 click_count:"{count, plural, one {# 回} other {# 回}} ク リ ッ ク し ま し た",

Salve o arquivo e abra o arquivo components/Footer.js para renderizar a tradução usando o componente FormattedMessage .

Então, encontre este elemento:

 

Você clicou {count} vezes

Substitua o acima pelo seguinte:

 

Também devemos importar o componente FormattedMessage do react-intl :

 import { //... FormattedMessage,
} de"react-intl";

Salve o arquivo novamente. Vamos recarregar o front-end e testar nosso trabalho.

Agora podemos adicionar suporte de tradução para os itens do menu. Primeiro, importe a FormattedMessage no arquivo components/Header.js assim:

 import {FormattedMessage} de"react-intl";

Precisamos acessar o menu individual chave usado no arquivo de tradução. Para fazer isso, vamos atualizar a matriz menu para incluir a chave :

 const menu=[ { chave:"about_project", //... }, { chave:"contact_us", //... },
];

Agora podemos usar as teclas para acessar as traduções na FormattedMessage .

Comece encontrando o seguinte código:

 {menu.map (({título, caminho})=> ( 
  • {title}
  • ))}

    Em seguida, substitua por este:

     {menu.map (({título, caminho, chave})=> ( 
  • ))}

    Salve o arquivo e teste o aplicativo.

    Para localizar o botão de frontend e seu texto de call to action, vamos atribuir chaves ao botão em nosso arquivo i18n/message.js .

    Para o objeto em inglês, adicione o seguinte:

     click_button:"Por favor, clique no botão abaixo",
    click_here:"clique aqui",
    

    Para francês, adicione este:

     click_button:"Veuillez cliquer sur le bouton ci-dessous",
    click_here:"Cliquez ici",
    

    Adicione traduções para outras localidades, como japonês e alemão, usando o código acima e o Google Translate.

    Assim que terminarmos, vamos abrir o components/Footer.js e substituir as strings de texto pela FormattedMessage :

     return ( 
    {/* Conteúdo do rodapé aqui */}

    {/*... */}
    );

    Salve os arquivos e recarregue o frontend. Observe que a descrição e o texto do botão foram atualizados em francês.

    Atualizado no aplicativo francês

    Adicionando a opção de mudar de local no frontend

    Para fornecer uma opção de alternar locais no front-end, devemos abrir o arquivo components/Header.js e adicionar o seguinte acima da instrução return :

    //Idiomas
    linguagens const=[ {nome:"Inglês", código: LOCALES.ENGLISH}, {nome:"日本語", código: LOCALES.JAPANESE}, {nome:"Français", código: LOCALES.FRENCH}, {nome:"Deutsche", código: LOCALES.GERMAN},
    ];
    

    Then, import the LOCALES at the top of the file:

    import { LOCALES } from"../i18n/locales";
    

    Next, we will loop through the languages array to generate our dropdown.

    Still in the file, locate this div container element:

    {/* Language switch dropdown here */}

    Then, update it to see the following:

    {/* Language switch dropdown here */} Languages{""}

    Save it and add this simple style in the src/index.css file:

    .switcher select { width: 99px; height: 30px;
    }
    

    Save the file again and view the dropdown in the frontend. At the moment, switching between languages doesn’t change the page content, so let’s address that.

    If familiar with form handling in React, this process should be a piece of cake. If not, that’s fine because we will do it together.

    In React, the form input should be a controlled input unlike that of the HTML form.

    To do this, we will add a value prop and an onChange event to the select element. The value prop is assigned the current locale while the onChange updates the value based on the user’s selection.

    For the meantime, update the select element to include these props:

    
    

    Since the IntlProvider is in the parent component, App.js must also know the current locale, so let’s set up the logic in the file.

    We can pass the necessary data down to the Header child component through the props. This process is called props drilling.

    Open the components/App.js and add a state whose default language is English:

    import { useState } from"react";
    ...
    const App=()=> { const locale=LOCALES.ENGLISH; const [currentLocale, setCurrentLocale]=useState(locale); return (  ...  );
    }; export default App;
    

    Don’t forget to import the useState Hook from React to get the current locale.

    Now, let’s pass the locale to the Header child component and use it in the select element.

    In the App.js file, update the

    instance in so we have the following:

    Save the file and open the Header.js to access the data; pass it to the value prop of the select element:

    ...
    const Header=(props)=> { ... return ( 
    ...
    {/* Language switch dropdown here */} Languages{""}
    ); }; export default Header;

    Call props the following:

    const Header=(props)=> { 

    Next, we will use the onChange event to handle updates.

    In the App.js file, add the following handler above the return statement and pass it down to the Header component through the props:

    const handleChange=(e)=> { setCurrentLocale(e.target.value);
    };
    

    The code now looks like this:

    ...
    const App=()=> { ... const handleChange=(e)=> { setCurrentLocale(e.target.value); }; return ( ... 
    ...
    ... ); };

    Save the file and access the handler inside the Header component.

    Simply update the select element so we have the following: