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.
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:
Instala react-i18next y la biblioteca central i18next:
npm install react-i18next i18nextEstos 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-backendUna 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.tsxreact-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"
}
}i18next admite dos enfoques principales para cargar traducciones: backend HTTP (carga diferida) y recursos empaquetados. Elige según las necesidades de tu aplicación.
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;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;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>
);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.
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>
);
}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."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"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>
);
}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-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>;
}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 errorPara 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>;
}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.
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:
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-CNAñade la automatización de traducciones a tu pipeline de construcción para que las traducciones estén siempre actualizadas:
{
"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"
}
}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 buildPara más detalles sobre la integración CI/CD y la automatización, consulta nuestra Guía de automatización de localización
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:
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.
Descubre por qué la traducción potenciada por IA es mejor para archivos de i18n que los métodos tradicionales.
Integra la localización potenciada por IA directamente en tu pipeline de CI/CD.
Incorpora la localización de IA en tu flujo de trabajo con nuestras extensiones y complementos.
react-i18next proporciona una solución de localización completa y lista para producción para aplicaciones de React. Con una API basada en hooks, soporte de espacios de nombres, integración con TypeScript y compatibilidad con SSR, maneja todos los requisitos de i18n que tu aplicación pueda tener.
Combina react-i18next con la traducción impulsada por IA de l10n.dev para eliminar el cuello de botella de la traducción. Traduce tus archivos JSON en segundos, intégralos en tu pipeline CI/CD y lanza globalmente con confianza.
Nuestra misión es hacer que la localización de software sea rápida, asequible y amigable para el desarrollador. Prueba l10n.dev hoy y mira cómo la IA puede transformar tu flujo de trabajo de localización de React.