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:
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 .
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:
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:
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:
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})=> (
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.
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 (); }; export default Header; ...{/* Language switch dropdown here */} Languages{""}
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:
Now we can test our application. It works! Awesome.
Ensure to translate the Languages text beside the dropdown list as well.
Persisting the selected locale in the browser local storage
Presently, if we switch from the default locale and reload the page, the content goes back to default. We don’t want that.
In this section, we’ll see how to easily persist the selected locale to the browser storage. This means the content in the user’s preferred language is still visible on the page when reloaded and on a subsequent visit, further improving the user’s experience.
First, open the App.js
file and add this code above the return
statement:
//localstorage function getInitialLocal() { //getting stored items const savedLocale=localStorage.getItem("locale"); return savedLocale || LOCALES.ENGLISH; }
Then, update the state to use this function:
const [currentLocale, setCurrentLocale]=useState(getInitialLocal());
Finally, update the handleChange
to include the storage object:
const handleChange=(e)=> { setCurrentLocale(e.target.value); //storing locale in the localstorage localStorage.setItem("locale", e.target.value); };
Remove this line from the App.js
file because it is now redundant:
const locale=LOCALES.ENGLISH;
Now, save the file and test the application. Ensure to reload the page to see that the data persists in the storage.
Because we started by accessing the local storage using the getItem()
method to check for any saved locale or return a fallback, the returned locale was assigned to the state variable, currentLocale
.
Likewise, we are also using the setItem()
method to save the user’s selected locale to the Storage
object.
Read about how to persist state of your React component in the local storage to learn more.
Conclusão
We’ve covered pretty much everything we need to know about the React Intl library. We’ve learned how to apply the library to a React application and how to persist the user’s selected locale in the local storage.
I hope you found this guide helpful. Should you have questions or contributions, I am in the comment section. You can also find the entire project source code in this GitHub repository.
The post React Intl: Internationalize your React apps appeared first on LogRocket Blog.