DEV Community 👩‍💻👨‍💻

Cover image for Internacionalizando seu app React com i18next
Aryclenio Barros
Aryclenio Barros

Posted on

Internacionalizando seu app React com i18next

Hoje em dia, nossas aplicações tem tomado proporções nunca antes imagináveis, e a web nos deu a possibilidade de fazer com que ele seja acessado por todo o mundo. É ai que muitos desenvolvedores enfrentam um problema...

Como fazer para que meu app seja traduzido de uma forma rápida e eficiente?

Para a nossa felicidade, bibliotecas como o React possuem alternativas extremamente fáceis de implementar essa funcionalidade, e hoje, vamos conhecer uma delas, o plugin i18next.

Implementando a internacionalização

Para começar, vamos as nossas dependências. Se você deseja iniciar um app do zero, vamos utilizar o comando abaixo e criar um novo app react:

yarn create react-app i18napp --template typescript
Enter fullscreen mode Exit fullscreen mode

Se você já tem um projeto ou acabou de criar o seu, instale as dependências que vamos precisar para que o i18next funcione da forma correta:

yarn add react-i18next i18next i18next-http-backend i18next-browser-languagedetector
Enter fullscreen mode Exit fullscreen mode

Pronto, agora já temos os pacotes que precisamos. Vamos por a mão no código!!!

Configurando o i18next

Para indicar ao nosso app o uso da internacionalização e ativar propriamente os hooks nele, devemos preparar um arquivo que ficará junto ao nosso index.js, ele se chamará i18n.js e conterá as seguintes linhas:

import i18n from 'i18next'
import Backend from 'i18next-http-backend'
import LanguageDetector from 'i18next-browser-languagedetector'
import { initReactI18next } from 'react-i18next'

i18n
  // Habilita o backend do i18next
  .use(Backend)
  // Habilita a detecção automática de linguagem
  .use(LanguageDetector)
  // Habilita o módulo de inicialização do hook
  .use(initReactI18next)
  .init({
    // Linguagem padrão utilizada
    fallbackLng: 'en',
    debug: true,
    // Detecta e guarda um cookie em cache da linguagem fornecida
    detection: {
      order: ['queryString', 'cookie'],
      cache: ['cookie']
    },
    interpolation: {
      escapeValue: false
    }
  })

export default i18n;
Enter fullscreen mode Exit fullscreen mode

Após isso, devemos importa-lo para nosso index.js, que ficará dessa forma:

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';
import * as serviceWorker from './serviceWorker';
import './i18n';

ReactDOM.render(
  <React.StrictMode>
    <Suspense fallback={<div>Loading...</div>}>
      <App />
    </Suspense>
  </React.StrictMode>,
  document.getElementById('root')
);

// If you want your app to work offline and load faster, you can change
// unregister() to register() below. Note this comes with some pitfalls.
// Learn more about service workers: https://bit.ly/CRA-PWA
serviceWorker.unregister();
Enter fullscreen mode Exit fullscreen mode

Pronto, o react i18next está habilitado e pronto para uso. Agora o próximo passo é incorporar nosas traduções.

Incorporando os locales

Internacionalizações na web funcionam a base de json com seções de palavras. Nesse app, vamos incorporar a língua inglesa e portuguesa.

Para isso, em nossa pasta /public vamos adicionar a pasta /locales que terá duas subpastas, /en e /pt, ambas com um arquivo translation.json que conterá o objeto com as traduções. Veja um exemplo do arquivo em inglês e a estrutura da pasta produzida:

{
  "title": "Welcome to an internationalized APP",
  "description": {
    "part1": "To get started, edit <1>src/App.js</1> and save to reload.",
    "part2": "Switch language between english and german using buttons above."
  }
}
Enter fullscreen mode Exit fullscreen mode

Estrutura da pasta locales

Alt Text

Feito isso, vamos por a mão na massa com nossa página inicial.

Personalizando o App.js

Agora vamos para nossa parte final, construir nossa página inicial. Para isso, vamos apagar o conteúdo original do App.js e deixar somente uma div.

Importando o hook de tradução

Para importar o hook do i18next utilizamos o seguinte código:

import { useTranslation } from "react-i18next";

function App() {
  const { t, i18n } = useTranslation();
Enter fullscreen mode Exit fullscreen mode

O atributo t é usado para incorporar nossa tradução e o i18n para observar as mudanças no estado da localização.

Utilizando a tradução em tags

Para utilizar um atributo do nosso objeto, apenas chamamos a função t() que desestruturamos acima:

   <div><h1>{t("title")}</h1></div>
Enter fullscreen mode Exit fullscreen mode

Viu como é facil?

Vamos completar nosso app com o código abaixo adicionando dois botões que mudarão a linguagem e ver a mágica em tempo real...

import React from "react";
import "./App.css";
import { useTranslation } from "react-i18next";

function App() {
  const { t, i18n } = useTranslation();

  const changeLanguage = (language) => {
    i18n.changeLanguage(language);
  };

  return (
    <div className="App">
      <button onClick={() => changeLanguage("en")}>EN</button>
      <button onClick={() => changeLanguage("pt")}>PT</button>
      <hr />
      <div><h1>{t("title")}</h1></div>
      <div>{t("description.part1")}</div>
      <div>{t("description.part2")}</div>
    </div>
  );
}

export default App;
Enter fullscreen mode Exit fullscreen mode

Observando a mágica

Se você inseriu o código da forma correta, a mágica abaixo deve acontecer com seu app. A tradução é feita em tempo de execução.

Alt Text

Gostou? O código está disponivel no meu github.

Obrigado pela leitura!!!

Top comments (1)

Collapse
 
igorthierry profile image
Igor Thierry

para que serve o i18next-http-backend?

typescript

11 Tips That Make You a Better Typescript Programmer

1 Think in {Set}

Type is an everyday concept to programmers, but it’s surprisingly difficult to define it succinctly. I find it helpful to use Set as a conceptual model instead.

#2 Understand declared type and narrowed type

One extremely powerful typescript feature is automatic type narrowing based on control flow. This means a variable has two types associated with it at any specific point of code location: a declaration type and a narrowed type.

#3 Use discriminated union instead of optional fields

...

Read the whole post now!