Centro de Ayuda

Localización de React con i18next

Crear una aplicación de React para una audiencia global requiere una estrategia de internacionalización (i18n) sólida. react-i18next es la biblioteca de localización de React más popular, construida sobre el framework i18next, probado en combate. Esta guía te lleva a través de todo lo que necesitas para localizar tu aplicación de React, desde la configuración inicial hasta la automatización lista para producción con traducción impulsada por IA.

¿Por qué elegir react-i18next para la localización de React?

react-i18next es el estándar de facto para la internacionalización de React, en el que confían miles de aplicaciones en producción en todo el mundo. He aquí por qué los desarrolladores lo eligen:

  • API basada en hooks - El hook useTranslation() proporciona una integración con React limpia e idiomática con renderizado automático al cambiar el idioma.
  • Ecosistema rico - Plugins para detección de idioma, backends HTTP, almacenamiento en caché y más. Extiende la funcionalidad sin reinventar la rueda.
  • Formato de traducción JSON - Utiliza archivos JSON estándar que son fáciles de editar, controlar por versiones e integrar con herramientas de traducción y servicios de IA.
  • Soporte de espacios de nombres (namespaces) - Organiza las traducciones en grupos lógicos (auth, dashboard, errors) para una mejor mantenibilidad y carga diferida (lazy loading).
  • Listo para SSR y Next.js - Funciona perfectamente con renderizado del lado del servidor, React Server Components y el App Router de Next.js.
  • Soporte para TypeScript - Seguridad de tipos completa para las claves de traducción con autocompletado, detectando claves faltantes en tiempo de compilación.

Instalación

Instala react-i18next y la biblioteca central i18next:

npm install react-i18next i18next

Plugins opcionales

Estos populares plugins mejoran tu configuración de i18next con detección automática de idioma y traducciones de carga diferida:

# Language detector (auto-detects user language)
npm install i18next-browser-languagedetector

# HTTP backend (load translations from server)
npm install i18next-http-backend

Estructura de proyecto recomendada

Una estructura de proyecto bien organizada mantiene tus traducciones mantenibles a medida que añades más idiomas:

src/
├── i18n/
│   └── i18n.ts                  ← i18next configuration
├── locales/
│   ├── en/
│   │   └── translation.json     ← English (source)
│   ├── fr/
│   │   └── translation.json     ← French
│   ├── de/
│   │   └── translation.json     ← German
│   ├── ja/
│   │   └── translation.json     ← Japanese
│   └── es/
│       └── translation.json     ← Spanish
├── components/
├── App.tsx
└── index.tsx

Formato de archivo JSON de traducción

react-i18next utiliza archivos JSON anidados para las traducciones. Las claves admiten notación de puntos, interpolación con {{variables}} y pluralización integrada:

// locales/en/translation.json
{
  "welcome": {
    "title": "Welcome to our platform",
    "greeting": "Hello, {{name}}!",
    "description": "Explore features and get started."
  },
  "nav": {
    "home": "Home",
    "dashboard": "Dashboard",
    "settings": "Settings",
    "logout": "Log out"
  },
  "cart": {
    "empty": "Your cart is empty",
    "item_one": "{{count}} item in your cart",
    "item_other": "{{count}} items in your cart",
    "checkout": "Proceed to checkout"
  }
}
  • Claves anidadas - Organiza las traducciones jerárquicamente (ej. welcome.title, nav.home) para una estructura clara.
  • Interpolación - Usa la sintaxis {{variableName}} para valores dinámicos que se insertan en tiempo de ejecución.
  • Pluralización - Añade sufijos _one y _other (o _zero, _two, _few, _many para idiomas complejos) para el manejo automático de plurales.
  • Contexto - Usa sufijos _male, _female para traducciones específicas de género cuando sea necesario.

Configuración de i18next

i18next admite dos enfoques principales para cargar traducciones: backend HTTP (carga diferida) y recursos empaquetados. Elige según las necesidades de tu aplicación.

Backend HTTP (Recomendado para aplicaciones grandes)

Carga traducciones bajo demanda desde archivos JSON en tu servidor. Esto mantiene tu paquete inicial pequeño y es ideal para aplicaciones con muchos idiomas o archivos de traducción grandes:

// src/i18n/i18n.ts
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import HttpBackend from "i18next-http-backend";

i18n
  .use(HttpBackend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: "en",
    supportedLngs: ["en", "fr", "de", "ja", "es"],
    defaultNS: "translation",
    interpolation: {
      escapeValue: false, // React already escapes by default
    },
    backend: {
      loadPath: "/locales/{{lng}}/{{ns}}.json",
    },
    detection: {
      order: ["localStorage", "navigator", "htmlTag"],
      caches: ["localStorage"],
    },
  });

export default i18n;

Recursos empaquetados (Enfoque simple)

Importa traducciones directamente al paquete. Es mejor para aplicaciones pequeñas o cuando necesitas que las traducciones estén disponibles inmediatamente sin solicitudes de red:

// src/i18n/i18n.ts — Bundled approach (no HTTP backend)
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";

import en from "../locales/en/translation.json";
import fr from "../locales/fr/translation.json";
import de from "../locales/de/translation.json";

i18n
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    fallbackLng: "en",
    supportedLngs: ["en", "fr", "de"],
    defaultNS: "translation",
    interpolation: {
      escapeValue: false,
    },
    resources: {
      en: { translation: en },
      fr: { translation: fr },
      de: { translation: de },
    },
  });

export default i18n;

Inicialización en tu aplicación

Importa el archivo de configuración de i18n en el punto de entrada de tu aplicación antes de renderizar cualquier componente. Esto asegura que las traducciones se carguen antes de que se renderice tu interfaz:

// src/index.tsx
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
import "./i18n/i18n"; // Initialize i18next before rendering

const root = ReactDOM.createRoot(
  document.getElementById("root") as HTMLElement
);

root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

Traducción de componentes de React

react-i18next proporciona dos APIs principales para traducir componentes: el hook useTranslation para acceso programático y el componente Trans para texto enriquecido con JSX.

Hook useTranslation

El hook useTranslation es la forma más común de acceder a las traducciones en componentes funcionales. Proporciona la función t() y se vuelve a renderizar automáticamente cuando cambia el idioma:

import { useTranslation } from "react-i18next";

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

  return (
    <div>
      <h1>{t("welcome.title")}</h1>
      <p>{t("welcome.greeting", { name: "Alice" })}</p>
      <p>{t("welcome.description")}</p>
    </div>
  );
}

Componente Trans para texto enriquecido

Cuando las traducciones contienen elementos HTML o JSX (negrita, enlaces, etc.), usa el componente Trans. Conserva tu árbol de componentes de React dentro de las traducciones:

import { Trans } from "react-i18next";

function RichTextExample() {
  return (
    <p>
      <Trans i18nKey="richText.welcome">
        Welcome to <strong>our platform</strong>.
        Visit your <a href="/dashboard">dashboard</a> to get started.
      </Trans>
    </p>
  );
}

// In the translation file:
// "richText.welcome": "Welcome to <1>our platform</1>. Visit your <3>dashboard</3> to get started."

Manejo de la pluralización

i18next maneja las formas plurales automáticamente basándose en las reglas de plurales ICU para cada idioma. Pasa un parámetro de conteo (count) e i18next selecciona la forma plural correcta:

// In translation JSON:
// "cart.item_one": "{{count}} item in your cart"
// "cart.item_other": "{{count}} items in your cart"

import { useTranslation } from "react-i18next";

function CartSummary({ itemCount }: { itemCount: number }) {
  const { t } = useTranslation();

  return (
    <p>{t("cart.item", { count: itemCount })}</p>
  );
}

// itemCount=0 → "0 items in your cart"
// itemCount=1 → "1 item in your cart"
// itemCount=5 → "5 items in your cart"
  • Añade sufijos _one y _other a tus claves de traducción para inglés
  • Para idiomas con reglas de plurales complejas (árabe, polaco, ruso), añade sufijos _zero, _two, _few, _many según sea necesario
  • i18next selecciona automáticamente la forma correcta basándose en las reglas de plurales CLDR del idioma de destino

Organización con espacios de nombres (namespaces)

Los espacios de nombres te permiten dividir las traducciones en archivos separados por característica o dominio. Esto mejora la mantenibilidad y permite la carga diferida de paquetes de traducción:

// src/i18n/i18n.ts
i18n.init({
  defaultNS: "common",
  ns: ["common", "dashboard", "auth", "errors"],
  backend: {
    loadPath: "/locales/{{lng}}/{{ns}}.json",
  },
});

// Usage in components:
import { useTranslation } from "react-i18next";

function DashboardPage() {
  // Load specific namespace
  const { t } = useTranslation("dashboard");

  return <h1>{t("title")}</h1>;
}

function LoginForm() {
  // Load multiple namespaces
  const { t } = useTranslation(["auth", "common"]);

  return (
    <form>
      <h2>{t("auth:login.title")}</h2>
      <button>{t("common:submit")}</button>
    </form>
  );
}

Cambio dinámico de idioma

react-i18next hace que el cambio de idioma sea fluido. Llama a i18n.changeLanguage() y todos los componentes que usan useTranslation se volverán a renderizar automáticamente con el nuevo idioma:

import { useTranslation } from "react-i18next";

const LANGUAGES = [
  { code: "en", label: "English" },
  { code: "fr", label: "Français" },
  { code: "de", label: "Deutsch" },
  { code: "ja", label: "日本語" },
  { code: "es", label: "Español" },
];

function LanguageSwitcher() {
  const { i18n } = useTranslation();

  const changeLanguage = (lng: string) => {
    i18n.changeLanguage(lng);
  };

  return (
    <select
      value={i18n.language}
      onChange={(e) => changeLanguage(e.target.value)}
    >
      {LANGUAGES.map(({ code, label }) => (
        <option key={code} value={code}>
          {label}
        </option>
      ))}
    </select>
  );
}

React Suspense y carga diferida

react-i18next se integra con React Suspense para manejar la carga de traducciones asíncronas de forma elegante. Al usar el backend HTTP, Suspense proporciona un estado de carga limpio mientras se obtienen las traducciones:

import { Suspense } from "react";
import { useTranslation } from "react-i18next";

// i18next supports React Suspense for async translation loading
function App() {
  return (
    <Suspense fallback={<div>Loading translations...</div>}>
      <MainContent />
    </Suspense>
  );
}

function MainContent() {
  const { t, ready } = useTranslation();

  // With Suspense, 'ready' is always true here
  return <h1>{t("welcome.title")}</h1>;
}

Claves de traducción con seguridad de tipos en TypeScript

i18next admite una integración completa con TypeScript. Al aumentar el módulo i18next, obtienes autocompletado y comprobación en tiempo de compilación para todas las claves de traducción, evitando errores tipográficos y traducciones faltantes:

// src/i18n/types.ts
import "i18next";
import translation from "../locales/en/translation.json";

declare module "i18next" {
  interface CustomTypeOptions {
    defaultNS: "translation";
    resources: {
      translation: typeof translation;
    };
  }
}

// Now t() calls are fully type-safe:
// t("welcome.title")       ✅ Autocomplete works
// t("welcome.greeting")    ✅ Valid key
// t("invalid.key")         ❌ TypeScript error
Las claves con seguridad de tipos funcionan con useTranslation, el componente Trans y todas las APIs de i18next. Las claves faltantes o mal escritas se marcan como errores de TypeScript en tu IDE.

Renderizado del lado del servidor con Next.js

Para aplicaciones Next.js que usan el App Router, puedes usar i18next tanto en componentes de servidor como de cliente. Crea una instancia de i18next separada para las traducciones del lado del servidor para evitar compartir el estado entre solicitudes:

// next-i18next.config.js (Next.js App Router)
// For Next.js 13+ with App Router, use next-intl or i18next directly

// src/i18n/server.ts
import { createInstance } from "i18next";
import { initReactI18next } from "react-i18next/initReactI18next";

export async function getServerTranslation(lng: string) {
  const i18nInstance = createInstance();
  await i18nInstance.use(initReactI18next).init({
    lng,
    fallbackLng: "en",
    resources: {
      [lng]: {
        translation: (await import(`../locales/${lng}/translation.json`)).default,
      },
    },
  });
  return i18nInstance;
}

// In a Server Component:
export default async function Page({ params }: { params: { lng: string } }) {
  const i18n = await getServerTranslation(params.lng);
  const t = i18n.t.bind(i18n);

  return <h1>{t("welcome.title")}</h1>;
}
  • Crea una nueva instancia de i18next por solicitud en el servidor para evitar fugas de estado entre usuarios
  • Usa los mismos archivos JSON de traducción tanto para el renderizado del servidor como del cliente
  • Considera i18next-resources-to-backend o next-intl como alternativas para configuraciones complejas de Next.js

Acelera la traducción con IA

Configurar react-i18next es solo la mitad de la batalla; todavía necesitas traducciones de alta calidad para cada idioma de destino. Traducir manualmente docenas de archivos JSON es lento, costoso y propenso a errores. La traducción impulsada por IA cambia las reglas del juego.

¿Por qué usar l10n.dev para React i18next?

l10n.dev está diseñado específicamente para flujos de trabajo de localización de desarrolladores. Entiende tus archivos de traducción JSON de forma nativa y produce traducciones que se sienten naturales, no generadas por máquina:

  • Soporte JSON nativo — Sube tu translation.json y obtén archivos JSON perfectamente formateados y listos para usar
  • IA consciente del contexto — Entiende el dominio de tu aplicación, preservando términos técnicos y la voz de marca en todos los idiomas
  • Seguro para la interpolación — Preserva {{variables}}, sufijos de plural (_one, _other) y estructuras de claves anidadas
  • Traducción por lotes — Traduce a más de 10 idiomas simultáneamente en segundos, no días
  • Integración CI/CD — Automatiza las traducciones como parte de tu pipeline de construcción con el paquete npm ai-l10n

Flujo de trabajo de traducción con IA

  1. Escribe tu translation.json fuente en inglés (o tu idioma base)
  2. Súbelo a l10n.dev o ejecuta la CLI ai-l10n para traducir
  3. La IA genera traducciones contextualmente precisas para todos los idiomas de destino
  4. Coloca los archivos JSON traducidos en tu directorio locales/ y despliega

Automatiza traducciones con la CLI ai-l10n

El paquete npm ai-l10n integra la traducción por IA directamente en tu flujo de trabajo de desarrollo. Traduce tus archivos JSON desde la línea de comandos:

# Install the l10n.dev CLI
npm install ai-l10n

# Translate your JSON files to multiple languages at once
npx ai-l10n translate src/locales/en/translation.json \
  --languages fr,de,ja,es,ko,zh-CN

Integración en la construcción (Build)

Añade la automatización de traducciones a tu pipeline de construcción para que las traducciones estén siempre actualizadas:

Scripts de package.json

{
  "scripts": {
    "translate": "ai-l10n translate src/locales/en/translation.json --languages fr,de,ja,es,ko --update",
    "pretranslate": "npm run translate",
    "dev": "vite",
    "build": "npm run translate && vite build"
  }
}

Makefile

LANGUAGES = fr,de,ja,es,ko,zh-CN

translate:
	npx ai-l10n translate src/locales/en/translation.json --languages $(LANGUAGES) --update

dev: translate
	npx vite

build: translate
	npx vite build

Para más detalles sobre la integración CI/CD y la automatización, consulta nuestra Guía de automatización de localización

Extensión de VS Code para traducción JSON

Traduce tus archivos JSON de React i18next directamente desde VS Code. La extensión l10n.dev te permite traducir archivos sin salir de tu editor:

Cómo funciona

  1. Instala la extensión l10n.dev desde el Marketplace de VS Code
  2. Abre tu archivo translation.json fuente
  3. Haz clic derecho y selecciona 'Translate with l10n.dev'
  4. Elige tus idiomas de destino y obtén los archivos traducidos al instante

Empieza a localizar tu aplicación de React hoy mismo

Ahora tienes todo lo que necesitas para construir una aplicación de React totalmente localizada con react-i18next. Combina el poder del ecosistema maduro de i18next con la traducción impulsada por IA para lanzar tu aplicación en cualquier idioma, rápidamente.