Recentemente, trabalhei em um projeto empolgante que envolveu a criação de um site capaz de alternar entre idiomas para atrair um público mais amplo. Isso me fez entender melhor o conceito de “localização”, que normalmente envolve adaptar o conteúdo para torná-lo relevante, acessível e identificável para usuários em diferentes idiomas e regiões.
Localização não se trata apenas de traduzir palavras, mas de criar uma experiência que faça os usuários se sentirem em casa, independentemente do seu idioma. Por exemplo, plataformas globais como a Amazon tornam a troca de idioma tão fluida que parece quase mágica. Além de melhorar a experiência do usuário, esse recurso desempenha um papel crucial em impulsionar negócios ao alcançar um público mais amplo e fomentar conexões mais fortes com clientes em todo o mundo.
Índice
O que é i18n e por que usá-lo?
i18n, abreviação de internacionalização, significa que um aplicativo suporta múltiplas línguas. “i18n” é derivado do fato de que há 18 letras entre o primeiro “i” e o último “n” em “internacionalização.” É tudo sobre tornar seu aplicativo adaptável para audiências globais, lidando com tradução de texto, formatando datas e números, gerenciando moedas e acomodando convenções regionais.
Ao habilitar a internacionalização, seu aplicativo se torna não apenas uma ferramenta, mas uma plataforma inclusiva que fala diretamente à preferência e cultura do usuário.
Vamos direto ao ponto
Vamos criar uma aplicação web multilíngue muito simples com um recurso de alternância de modo escuro para demonstrar como alcançar esse conceito.
Pré-requisitos
-
Conhecimento Básico de React – Você deve entender como criar componentes, gerenciar estado e usar Hooks como
useState
euseEffect
. Se você é novo no React, recomendo começar com a documentação oficial do React para uma base sólida. -
Familiaridade com Conceitos de Internacionalização – Saber o básico da internacionalização (i18n) e por que é importante fornecerá contexto para o projeto. As seções anteriores deste artigo cobrem os fundamentos.
-
Tailwind CSS – Vamos usar o Tailwind CSS para estilização. É um framework de CSS de primeira utilidade que ajuda a construir designs modernos e responsivos sem sair do seu HTML. Se você não conhece, confira a documentação do Tailwind.
-
Node.js – Certifique-se de que o Node.js esteja instalado em seu sistema para lidar com dependências. Você pode baixar a última versão em Node.js.
-
Gerenciador de Pacotes – É necessário ter npm (incluído com o Node.js) ou yarn para gerenciar as dependências do projeto
Ferramentas que vamos usar
-
Editor de Código
-
Biblioteca de Localização: react-i18next
-
Biblioteca de Ícones: hero-icons
Passo 1: Como Configurar o Projeto
Inicialize o Projeto
Use o Vite para configuração rápida:
npm create vite@latest multilingual-demo
Siga as instruções que aparecem no seu terminal, selecionando React e TypeScript para desenvolvimento conforme mostrado na imagem abaixo:
Instalar Dependências
Execute os seguintes comandos no seu terminal para instalar as dependências necessárias para este projeto:
npm install i18next react-i18next i18next-browser-languagedetector i18next-http-backend heroicons
npm install tailwindcss postcss autoprefixer
npx tailwindcss init
Configure o TailwindCSS
Atualize o arquivo tailwind.config.ts
:
/** @type {import('tailwindcss').Config} */
module.exports = {
content: ["./src/**/*.{js,jsx,ts,tsx}"],
darkMode: "class", //Para a nossa funcionalidade de modo escuro
theme: {
container: {
center: true,
padding: "1.25rem",
screens: {
sm: "1200px",
},
},
extend: {},
},
plugins: [],
};
Adicione TailwindCSS ao arquivo src/index.css
:
@tailwind base;
@tailwind components;
@tailwind utilities;
Passo 2: Como Configurar a Internacionalização com i18next
Inicialize o i18next
Crie um arquivo i18n.tsx
na pasta src
e configure o i18next:
import i18next from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";
import Backend from "i18next-http-backend";
i18next.use(LanguageDetector).use(initReactI18next).use(Backend).init({
returnObjects: true,
fallbackLng: "en", // Idioma para retornar se o selecionado não estiver configurado
debug: true, // Para nos permitir ver erros
// lng: "en", // Idioma padrão como inglês
});
Vamos dar uma olhada rápida no conteúdo deste arquivo, pois ele desempenha um papel fundamental na ativação da funcionalidade de tradução. Este arquivo é responsável por configurar o núcleo do processo de tradução e garantir que a funcionalidade de troca de idioma funcione sem problemas em seu aplicativo.
-
i18next
: A biblioteca interna de internacionalização que estamos usando para tradução. -
LanguageDetector
: Nos ajuda a detectar automaticamente o idioma preferido do usuário, com base nas configurações do navegador. -
initReactI18next
: É responsável por integrar o plugini18next
com o React e fornece Hooks como o HookuseTranslation
e outros utilitários. -
Backend
: Busca dinamicamente dados de tradução de uma fonte externa. Neste caso, estaremos usando arquivos JSON.
Importe este arquivo no arquivo main.tsx
:
//main.tsx
import React, { StrictMode } from "react";
import { createRoot } from "react-dom/client";
import "./index.css";
import App from "./App.tsx";
import "./i18n.tsx"; //Importe aqui
createRoot(document.getElementById("root")!).render(
<StrictMode>
<React.Suspense fallback="loading">
<App />
</React.Suspense>
</StrictMode>
);
Criar Arquivos de Tradução
No diretório public/locales
, crie subpastas para cada idioma (por exemplo, en
, fr
) e inclua arquivos translation.json
:
en/translation.json
{
"greeting": "Welcome to the Language Playground",
"detail": {
"line1": "Did you know that over 7,000 languages are spoken worldwide?",
"line2": "This Playground demonstrates how web applications can support users in multiple languages, making them accessible and inclusive to people from different backgrounds."
}
}
fr/translation.json
{
"greeting": "Bienvenue sur le terrain de jeu linguistique",
"detail": {
"line1": "Saviez-vous que plus de 7 000 langues sont parlées dans le monde ?",
"line2": "Ce terrain de jeu démontre comment les applications web peuvent prendre en charge les utilisateurs dans plusieurs langues, les rendant accessibles et inclusives aux personnes de différents horizons."
}
}
Aqui, você pode adicionar quantos idiomas desejar com seus arquivos de tradução que serão fornecidos ao i18next
. Note que as chaves nos arquivos JSON são as mesmas que serão usadas como referências ao exibi-las no site.
Passo 3: Como Construir Componentes
Crie uma pasta components
no diretório src
e adicione os seguintes componentes:
Seletor de Idioma
Crie o componente LanguageSelector
– contém um elemento select
para ajudar os usuários a trocar de idioma dinamicamente:
import { useEffect, useState } from "react";
import i18next from "i18next";
import { useTranslation } from "react-i18next";
type languageOption = { language: string; code: string };
const languageOptions: languageOption[] = [
{
language: "English",
code: "en",
},
{ language: "French", code: "fr" },
{ language: "German", code: "de" },
{ language: "Spanish", code: "es" },
{ language: "Arabic", code: "ar" },
{ language: "Yoruba", code: "yo" },
];
const LanguageSelector = () => {
// Defina o idioma inicial detectado pelo i18next ou o idioma padrão
const [language, setLanguage] = useState(i18next.language);
const { i18n } = useTranslation();
const handleLanguageChange = (e: React.ChangeEvent<HTMLSelectElement>) => {
const selectedLanguage = e.target.value;
setLanguage(selectedLanguage);
i18next.changeLanguage(selectedLanguage); // Atualize o idioma no i18next
};
useEffect(() => {
document.body.dir = i18n.dir(); // Define o corpo para ltr ou rtl
}, [i18n, i18n.language]);
return (
<select
id="language"
value={language}
onChange={handleLanguageChange}
className="p-2 border border-gray-300 rounded-md shadow-sm focus:border-indigo-500 focus:ring focus:ring-indigo-200 focus:ring-opacity-50
dark:bg-gray-800 dark:border-gray-600 dark:text-gray-200 dark:focus:border-indigo-400 dark:focus:ring-indigo-700 dark:focus:ring-opacity-50"
>
{languageOptions.map(({ language, code }, key) => (
<option value={code} key={key}>
{language}
</option>
))}
</select>
);
};
export default LanguageSelector;
-
Inicialize o idioma com o idioma detectado pelo
i18next
ou o idioma padrão definido. -
O Hook
useTranslation
expõe a instância doi18n
doi18next
para interagir com as configurações de internacionalização. -
A função
handleLanguageChange
seria usada para atualizar o idioma selecionado pelo usuário. É acionada quando o usuário seleciona um novo idioma no menu suspenso.
Implementando a Direção do Texto
O atributo dir
em HTML é um recurso crítico para garantir acessibilidade e inclusão em aplicações web, especialmente ao lidar com idiomas que diferem na direção do texto. Por exemplo:
-
Da Esquerda para a Direita (LTR): A maioria dos idiomas, incluindo inglês, francês e espanhol, seguem essa direção.
Da Direita para a Esquerda (RTL): Idiomas como árabe e hebraico exigem que o alinhamento e layout do texto sejam invertidos para manter a legibilidade e contexto cultural.
Para alcançar isso em nosso aplicativo, definimos o document.body.dir
para o dir
do i18n
enquanto ouvimos as mudanças na seleção de idioma usando o gancho useEffect
Alternar Modo Escuro
Crie o componente DarkModeToggle
para alternar entre os modos claro e escuro conforme preferido pelo usuário.
import { useEffect, useState } from "react";
import { SunIcon, MoonIcon } from "@heroicons/react/solid";
const DarkModeToggle = () => {
const [darkMode, setDarkMode] = useState(false);
useEffect(() => {
// Verifique o armazenamento local ou preferência do sistema na primeira carga
const isDark =
localStorage.getItem("theme") === "dark" ||
(!localStorage.getItem("theme") &&
window.matchMedia("(prefers-color-scheme: dark)").matches);
setDarkMode(isDark);
document.documentElement.classList.toggle("dark", isDark);
}, []);
const toggleDarkMode = () => {
setDarkMode(!darkMode);
document.documentElement.classList.toggle("dark", !darkMode);
localStorage.setItem("theme", !darkMode ? "dark" : "light");
};
return (
<button
aria-label="Toggle dark mode"
onClick={toggleDarkMode}
className="p-1 rounded"
>
{darkMode ? (
<SunIcon
className="w-6 h-6 text-yellow-500 "
onClick={toggleDarkMode}
/>
) : (
<MoonIcon className="w-6 h-6 text-gray-900 " onClick={toggleDarkMode} />
)}
</button>
);
};
export default DarkModeToggle;
Componente de Cabeçalho
O componente Header
serve como um componente pai para os componentes DarkModeToggle
e languageSelector
.
import DarkModeToggle from "./DarkModeToggle";
import LanguageSelector from "./LanguageSelector";
const Header = () => {
return (
<header className="container flex justify-between">
<DarkModeToggle />
<LanguageSelector />
</header>
);
};
export default Header;
Passo 4: Componente Principal do Aplicativo
No arquivo src/app
, inclua o seguinte:
import { useTranslation } from "react-i18next";
import Header from "./components/Header";
const App = () => {
const { t } = useTranslation();
const line1 = t("detail.line1");
const line2 = t("detail.line2");
return (
<div className="h-[100vh] bg-white text-black dark:bg-gray-900 dark:text-white py-8">
<Header />
<div className="container text-center max-w-2xl mt-28">
<h1 className="text-4xl font-bold">{t("greeting")}</h1>
<p className="mt-8">{line1}</p>
<p className="mt-2">{line2}</p>
</div>
</div>
);
};
export default App;
-
O
useTranslation
Hook doreact-i18next
expõe a funçãot
, que é usada para buscar texto traduzido. -
Ela busca a string traduzida com base em uma chave dos seus arquivos de tradução (por exemplo,
en.json
,fr.json
).
Seguindo esses passos, seu aplicativo deve estar agora totalmente funcional com traduções integradas de forma fluida. É assim que o resultado final do nosso aplicativo se parece:
Confira a demonstracão ao vivo e o código fonte no GitHub
Conclusão
Criar sites que permitem aos usuários selecionar seu idioma preferido não é apenas uma conquista técnica, mas um passo em direção a tornar a web mais inclusiva e acolhedora.
Combinando internacionalização (i18n) com ferramentas como React-i18next e estilização com Tailwind CSS, você pode construir aplicações que são flexíveis, amigáveis ao usuário e acessíveis a uma audiência global.
Neste projeto, percorremos a configuração do i18n, adicionando um seletor de idiomas e incluindo o “modo escuro” para melhor usabilidade.
Referências
Source:
https://www.freecodecamp.org/news/build-multilingual-apps-with-i18n-in-react/