Traducción de React con react-i18next: Guía completa

Aprenda a traducir una aplicación React con react-i18next, incluyendo internacionalización de React, plurales, contenido dinámico y traducción de archivos JSON.

Al finalizar esta guía, dispondrá de una configuración de localización de React funcional que cambia de idioma en tiempo real y está lista para tantos idiomas como necesite.

Ejemplo de internacionalización de React

Los pasos siguientes describen un ejemplo completo de i18n de React, incluyendo la inicialización de i18next, la traducción de texto, el manejo de la pluralización y la adición de un selector de idiomas.

Puede seguir la demostración completa de localización de React en GitHub.

1

Configure su aplicación de React

Esta guía utiliza una aplicación React + TypeScript creada con Vite. Si está añadiendo react-i18next a una aplicación existente, vaya al paso 2.

Para crear una nueva aplicación de React + TypeScript, ejecute:

npm create vite@latest react-localization-demo -- --template react-ts
cd react-localization-demo
npm install
npm run dev

Esto inicia un servidor de desarrollo y abre la página predeterminada de Vite + React en su navegador.

2

Instale y configure react-i18next

Instale las bibliotecas:

npm install i18next react-i18next

Cree la estructura de carpetas de i18n de React:

src/
  i18n/
    locales/
      en.json

Añada sus cadenas en inglés a src/i18n/locales/en.json:

{
  "welcome": "Welcome",
  "description": "This is a localization demo.",
  "clickMe": "Click me"
}

Cada clave (welcome, description, clickMe) se asigna al texto que desea mostrar en la interfaz de usuario.

Prepare sus componentes de React para la traducción

Este es un componente típico de React con cadenas codificadas:

function App() {
  return (
    <div>
      <h1>Welcome</h1>
      <p>This is a localization demo.</p>
      <button onClick={() => alert('Click me')}>Click me</button>
    </div>
  );
}

Reemplace el texto codificado con el hook useTranslation en src/App.tsx:

import { useTranslation } from 'react-i18next';

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

  return (
    <div>
      <h1>{t('welcome')}</h1>
      <p>{t('description')}</p>
      <button onClick={() => alert(t('clickMe'))}>{t('clickMe')}</button>
    </div>
  );
}

export default App;

useTranslation() proporciona a su componente acceso a:

  • t() – busca una cadena por clave
  • i18n – le permite cambiar de idioma mediante programación

3

Inicialice i18next en su aplicación React

Cree src/i18n/index.ts para configurar i18next y cargar los archivos de traducción automáticamente.

import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

type TranslationResources = string | { [k: string]: TranslationResources } | TranslationResources[];

const modules = import.meta.glob<{default: Record<string, TranslationResources>}>('./locales/*.json', { eager: true })

const resources: Record<string, { translation: Record<string, TranslationResources> }> = {};

for (const path in modules) {
  const lang = path.match(/\.\/locales\/(.*)\.json$/)?.[1];
  if (lang) {
    resources[lang] = { translation: modules[path].default };
  }
}

i18n
  .use(initReactI18next)
  .init({
    resources,
    fallbackLng: 'en',
    interpolation: { escapeValue: false },
  });

export default i18n;

El patrón import.meta.glob significa que cada archivo .json que añada a src/i18n/locales/ se detecta automáticamente. No se necesitan importaciones manuales cuando añada nuevos idiomas más adelante.

Importe i18n antes de que se renderice su aplicación

Abra src/main.tsx e importe la configuración de i18n:

import React from 'react'
import ReactDOM from 'react-dom/client'
import App from './App.tsx'
import './index.css'
import './i18n'  // ← Add this import!

ReactDOM.createRoot(document.getElementById('root')!).render(
  <React.StrictMode>
    <App />
  </React.StrictMode>,
)

Si omite este paso, t() simplemente devolverá las claves de traducción en lugar del texto traducido.

4

Maneje contenido dinámico en las traducciones de React

Las aplicaciones reales necesitan más que cadenas estáticas. Así es como react-i18next maneja los patrones de contenido dinámico más comunes.

Interpolación (variables) en i18next

Use la sintaxis {{variableName}} en su JSON y pase el valor a t().

Actualice src/i18n/locales/en.json:

{
  "welcome": "Welcome",
  "userGreeting": "Welcome back, {{firstName}}!",
  "description": "This is a localization demo.",
  "clickMe": "Click me"
}

Úselo en su componente:

import { useTranslation } from 'react-i18next';

function App() {
  const { t } = useTranslation();
  const user = { firstName: 'Sarah' };

  return (
    <div>
      <h1>{t('welcome')}</h1>
      <p>{t('userGreeting', { firstName: user.firstName })}</p>
      <p>{t('description')}</p>
      <button onClick={() => alert(t('clickMe'))}>{t('clickMe')}</button>
    </div>
  );
}

export default App;

El segundo argumento de t() es un objeto con los valores que desea sustituir. Puede tener tantas variables como necesite. Solo asegúrese de que cada una aparezca en sus traducciones.

Pluralización en React i18next

Use el patrón de sufijo _one / _other. La variable debe llamarse count:

Actualice src/i18n/locales/en.json:

{
  "welcome": "Welcome",
  "userGreeting": "Welcome back, {{firstName}}!",
  "description": "This is a localization demo.",
  "clickMe": "Click me",
  "newMessages_one": "You have {{count}} new message.",
  "newMessages_other": "You have {{count}} new messages."
}

Úselo en su componente:

import { useTranslation } from 'react-i18next';

function App() {
  const { t } = useTranslation();
  const user = { firstName: 'Sarah' };
  const [messageCount, setMessageCount] = useState<number>(1);

  const handleIncrement = () => {
    setMessageCount(messageCount + 1);
  };

  return (
    <div>
      <h1>{t('welcome')}</h1>
      <p>{t('userGreeting', { firstName: user.firstName })}</p>
      <p>{t('newMessages', { count: messageCount })}</p>
      <p>{t('description')}</p>
      <button onClick={handleIncrement}>{t('clickMe')}</button>
    </div>
  );
}

export default App;

i18next selecciona la forma plural correcta automáticamente. También maneja idiomas con más de dos formas plurales (como el polaco o el árabe) sin ninguna configuración adicional.

Para traducciones que contengan elementos HTML como enlaces o texto en negrita, use el componente Trans:

{
  "termsText": "I agree to the <1>Terms of Service</1> and <3>Privacy Policy</3>."
}

Las etiquetas <1> y <3> son placeholders basados en índices que se asignan a elementos secundarios (contando desde 0):

import { Trans } from 'react-i18next';

<Trans i18nKey="termsText">
  I agree to the <a href="/terms">Terms of Service</a> and
  <a href="/privacy">Privacy Policy</a>.
</Trans>

Esto mantiene sus elementos JSX en el componente mientras permite a los traductores reordenar el texto circundante de forma natural.

Traduzca los archivos JSON de su aplicación React

Su aplicación React ya está configurada para la internacionalización. El siguiente paso es producir los archivos de traducción reales para cada idioma.

PTC está diseñado exactamente para esto. Esta herramienta de localización con IA se integra directamente con su repositorio de GitHub, GitLab o Bitbucket. Lee su en.json de origen y abre una solicitud de extracción con archivos traducidos para cada idioma que necesite.

Debido a la configuración de carga automática que estableció en el paso 3, esos nuevos archivos funcionan inmediatamente sin necesidad de cambios en el código.

PTC comienza con una prueba gratuita de 30 días que le permite traducir 20.000 palabras a 2 idiomas. Después de eso, paga según el uso sin suscripción.

Si prefiere no integrarse con su repositorio, alternativamente puede:

Pruebe las traducciones de React con un selector de idiomas

Añada botones de idioma a src/App.tsx y verifique que su configuración de react-i18next funciona:

import { useTranslation } from 'react-i18next';

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

  return (
    <div>
      <h1>{t('welcome')}</h1>
      <p>{t('userGreeting', { firstName: user.firstName })}</p>
      <p>{t('newMessages', { count: messageCount })}</p>
      <p>{t('description')}</p>
      
      <p>
        <Trans i18nKey="termsText">
          I agree to the <a href="/terms">Terms of Service</a> and <a href="/privacy">Privacy Policy</a>.
        </Trans>
      </p>
      <button onClick={() => alert(t('clickMe'))}>{t('clickMe')}</button>

      <button onClick={() => i18n.changeLanguage('en')}>EN</button>
      <button onClick={() => i18n.changeLanguage('fr')}>FR</button>
    </div>
  );
}

Ejecute npm run dev y haga clic en los botones de idioma. El texto debería actualizarse inmediatamente sin recargar la página. Si es así, su configuración de i18n de React funciona correctamente.

Siguientes pasos: Optimice su configuración de localización de React

Su aplicación React ahora tiene soporte completo para múltiples idiomas. Hay algunas adiciones que vale la pena considerar antes de pasar a producción:

Detecte automáticamente el idioma del usuario

Instale i18next-browser-languagedetector para cargar automáticamente el idioma correcto desde la configuración del navegador del usuario, la URL o las preferencias guardadas:

npm install i18next-browser-languagedetector

Actualice src/i18n/index.ts:

    import i18n from "i18next";
    import { initReactI18next } from "react-i18next";
    import LanguageDetector from "i18next-browser-languagedetector";
    
    type TranslationResources = string | { [k: string]: TranslationResources } | TranslationResources[];
    
    const modules = import.meta.glob<{default: Record<string, TranslationResources>}>('./locales/*.json', { eager: true })
    
    const resources: Record<string, { translation: Record<string, TranslationResources> }> = {};
    
    for (const path in modules) {
      const lang = path.match(/\.\/locales\/(.*)\.json$/)?.[1];
      if (lang) {
        resources[lang] = { translation: modules[path].default };
      }
    }
    
    i18n
      .use(LanguageDetector) // detect browser/localStorage/etc.
      .use(initReactI18next)
      .init({
        resources,
        fallbackLng: "en",
        supportedLngs: ["en", "fr", "de", "ar"], // adjust to your languages
        interpolation: { escapeValue: false },
        detection: {
          order: ["querystring", "localStorage", "cookie", "navigator"],
          caches: ["localStorage", "cookie"],
        }
      });
    
    export default i18n;
    

    Carga diferida de traducciones

    De forma predeterminada, todos los archivos de traducción se empaquetan en tiempo de compilación. Para aplicaciones React con muchos idiomas, use i18next-http-backend para obtener solo los archivos de idioma que el usuario realmente necesita:

    npm install i18next-http-backend

    Actualice src/i18n/index.ts:

      import i18n from "i18next";
      import { initReactI18next } from "react-i18next";
      import Backend from "i18next-http-backend";
      import LanguageDetector from "i18next-browser-languagedetector";
      
      i18n
        .use(Backend) // load JSON over HTTP
        .use(LanguageDetector)
        .use(initReactI18next)
        .init({
          fallbackLng: "en",
          supportedLngs: ["en", "fr"],
          interpolation: { escapeValue: false },
          backend: {
            loadPath: "/locales/{{lng}}/{{ns}}.json"
          }
        });
      
      export default i18n;
      

      Mueva sus archivos de traducción a public/locales/ para que se sirvan como recursos estáticos:

        public/
          locales/
            en/
              translation.json
            fr/
              translation.json

        Con esta estructura, cambiar al francés obtiene /locales/fr/common.json bajo demanda en lugar de empaquetarlo con su aplicación. Esto mantiene su paquete inicial ligero independientemente de cuántos idiomas admita.

        Traduzca React con PTC

        Su aplicación React está lista para la internacionalización. Ahora deje que PTC se encargue de las traducciones.

        Sus primeras 20.000 palabras son gratuitas, sin suscripción requerida.

        Ir arriba