Respuesta rápida
i18next es el framework de internacionalización de JavaScript más popular con más de 8M de descargas npm semanales. Instálalo con npm install i18next, configúralo con i18n.init({ lng: 'en', resources: {...} }), y luego llama a i18n.t('key') para traducir. Funciona en cualquier entorno JavaScript—React, Vue, Node.js, vanilla JS, aplicaciones móviles. Para producción, combínalo con IntlPull para gestión de traducción impulsada por IA y colaboración en equipo.
¿Qué es i18next?
i18next es una librería de internacionalización (i18n) para JavaScript agnóstica del framework. Creada en 2011, es la solución i18n más probada en batalla con:
- Soporte universal: Navegador, Node.js, React Native, Electron, Deno
- Bindings de framework: React, Vue, Angular, Svelte, Next.js
- Ecosistema de plugins: 50+ plugins para backends, detección, caché
- Lista para empresas: Usada por compañías como Microsoft, Adobe, Airbnb
¿Por qué i18next?
| Característica | i18next | Otras Librerías |
|---|---|---|
| Descargas Semanales | 8M+ | Variable |
| Primer Lanzamiento | 2011 | Variable |
| Soporte de Framework | Todos | A menudo limitado |
| Sistema de Plugin | Extenso | Limitado |
| Comunidad | La más grande | Más pequeña |
| TypeScript | Excelente | Variable |
| Mantenimiento | Activo | Variable |
Conceptos Principales
1. Archivos de Traducción (Recursos)
Las traducciones se organizan como objetos JSON con claves anidadas:
JSON1{ 2 "greeting": "¡Hola!", 3 "nav": { 4 "home": "Inicio", 5 "about": "Sobre Nosotros" 6 }, 7 "buttons": { 8 "submit": "Enviar", 9 "cancel": "Cancelar" 10 } 11}
2. Namespaces (Espacios de nombres)
Los namespaces dividen las traducciones en grupos lógicos (como módulos de código):
locales/
├── en/
│ ├── common.json # Cadenas compartidas
│ ├── auth.json # Autenticación
│ └── dashboard.json # Página de dashboard
└── es/
├── common.json
├── auth.json
└── dashboard.json
3. Detección de Idioma
i18next puede detectar el idioma del usuario desde múltiples fuentes:
- Parámetro URL (
?lng=es) - Cookie
- localStorage
- Configuración del navegador
- Atributo lang de HTML
4. Cadena de Respaldo (Fallback Chain)
Cuando falta una traducción:
- Verifica idioma solicitado (es-MX)
- Verifica idioma padre (es)
- Verifica idioma de respaldo (en)
- Retorna la clave o valor por defecto
Configuración Básica
Instalación
Terminal1npm install i18next 2# o 3yarn add i18next 4# o 5pnpm add i18next
Configuración Mínima
JavaScript1import i18next from 'i18next'; 2 3i18next.init({ 4 lng: 'en', 5 resources: { 6 en: { 7 translation: { 8 greeting: 'Hello, World!', 9 welcome: 'Welcome to our app', 10 }, 11 }, 12 es: { 13 translation: { 14 greeting: '¡Hola, Mundo!', 15 welcome: 'Bienvenido a nuestra aplicación', 16 }, 17 }, 18 }, 19}); 20 21// Usar traducciones 22console.log(i18next.t('greeting')); // "Hello, World!"
Configuración Completa
JavaScript1import i18next from 'i18next'; 2 3i18next.init({ 4 // Configuración de idioma 5 lng: 'en', // Idioma actual 6 fallbackLng: 'en', // Respaldo cuando falta traducción 7 supportedLngs: ['en', 'es', 'fr', 'de'], 8 load: 'languageOnly', // 'en' en lugar de 'en-US' 9 10 // Configuración de Namespace 11 ns: ['common', 'auth', 'dashboard'], 12 defaultNS: 'common', 13 14 // Recursos (en línea o cargados vía backend) 15 resources: { 16 en: { common: {...}, auth: {...} }, 17 es: { common: {...}, auth: {...} }, 18 }, 19 20 // Interpolación 21 interpolation: { 22 escapeValue: false, // No necesario para React 23 formatSeparator: ',', 24 }, 25 26 // Configuración de claves 27 keySeparator: '.', // Para claves anidadas 28 nsSeparator: ':', // namespace:clave 29 30 // Claves faltantes 31 saveMissing: true, 32 missingKeyHandler: (lng, ns, key) => { 33 console.warn(`Falta: ${lng}/${ns}/${key}`); 34 }, 35 36 // Debug 37 debug: process.env.NODE_ENV === 'development', 38});
Interpolación de Variables
Variables Básicas
JSON1{ 2 "greeting": "Hola, {{name}}!", 3 "cartInfo": "Tienes {{count}} artículos por valor de {{total}}" 4}
JavaScript1i18next.t('greeting', { name: 'John' }); 2// "Hola, John!" 3 4i18next.t('cartInfo', { count: 5, total: '$99.99' }); 5// "Tienes 5 artículos por valor de $99.99"
Objetos Anidados
JSON{ "userInfo": "{{user.name}} ({{user.email}})" }
JavaScript1i18next.t('userInfo', { 2 user: { name: 'John', email: 'john@example.com' } 3}); 4// "John (john@example.com)"
Valores por Defecto
JavaScript1i18next.t('unknown.key', 'Texto por defecto'); 2// "Texto por defecto" (cuando la clave no existe) 3 4i18next.t('greeting', { name: 'Invitado', defaultValue: '¡Hola!' }); 5// Usa defaultValue si la clave falta
Formateo
JSON1{ 2 "price": "Total: {{amount, currency}}", 3 "date": "Creado: {{date, datetime}}" 4}
JavaScript1i18next.init({ 2 interpolation: { 3 format: (value, format, lng) => { 4 if (format === 'currency') { 5 return new Intl.NumberFormat(lng, { 6 style: 'currency', 7 currency: 'USD', 8 }).format(value); 9 } 10 if (format === 'datetime') { 11 return new Intl.DateTimeFormat(lng, { 12 dateStyle: 'medium', 13 }).format(value); 14 } 15 return value; 16 }, 17 }, 18}); 19 20i18next.t('price', { amount: 99.99 }); 21// "Total: $99.99"
Pluralización
Plurales Básicos
JSON1{ 2 "item_one": "{{count}} artículo", 3 "item_other": "{{count}} artículos" 4}
JavaScripti18next.t('item', { count: 1 }); // "1 artículo" i18next.t('item', { count: 5 }); // "5 artículos"
Conteo Cero
JSON1{ 2 "item_zero": "Sin artículos", 3 "item_one": "{{count}} artículo", 4 "item_other": "{{count}} artículos" 5}
Plurales Complejos
Idiomas como ruso y árabe tienen reglas plurales complejas:
JSON1{ 2 "item_zero": "нет товаров", 3 "item_one": "{{count}} товар", 4 "item_few": "{{count}} товара", 5 "item_many": "{{count}} товаров", 6 "item_other": "{{count}} товаров" 7}
i18next selecciona automáticamente la forma correcta basada en las reglas plurales CLDR.
Ordinales
JSON1{ 2 "rank_ordinal_one": "{{count}}er", 3 "rank_ordinal_two": "{{count}}do", 4 "rank_ordinal_few": "{{count}}er", 5 "rank_ordinal_other": "{{count}}to" 6}
JavaScript1i18next.t('rank', { count: 1, ordinal: true }); // "1er" 2i18next.t('rank', { count: 22, ordinal: true }); // "22do" 3i18next.t('rank', { count: 33, ordinal: true }); // "33er" 4i18next.t('rank', { count: 44, ordinal: true }); // "44to"
Contexto
Misma clave, diferente traducción basada en el contexto:
JSON1{ 2 "friend": "Un amigo", 3 "friend_male": "Un novio", 4 "friend_female": "Una novia" 5}
JavaScripti18next.t('friend'); // "Un amigo" i18next.t('friend', { context: 'male' }); // "Un novio" i18next.t('friend', { context: 'female' }); // "Una novia"
Combinando Contexto con Plurales
JSON1{ 2 "friend_male_one": "{{count}} novio", 3 "friend_male_other": "{{count}} novios", 4 "friend_female_one": "{{count}} novia", 5 "friend_female_other": "{{count}} novias" 6}
JavaScripti18next.t('friend', { context: 'male', count: 2 }); // "2 novios"
Namespaces
Cargando Múltiples Namespaces
JavaScript1i18next.init({ 2 ns: ['common', 'auth', 'dashboard'], 3 defaultNS: 'common', 4 resources: { 5 en: { 6 common: { submit: 'Submit' }, 7 auth: { login: 'Sign In' }, 8 dashboard: { title: 'Dashboard' }, 9 }, 10 }, 11}); 12 13i18next.t('submit'); // De common (default) 14i18next.t('auth:login'); // De namespace auth 15i18next.t('dashboard:title'); // De namespace dashboard
Carga Dinámica de Namespace
JavaScript1// Cargar namespace bajo demanda 2await i18next.loadNamespaces('settings'); 3 4// Verificar si el namespace está cargado 5i18next.hasLoadedNamespace('settings');
Sistema de Plugins
Detección de Idioma
JavaScript1import i18next from 'i18next'; 2import LanguageDetector from 'i18next-browser-languagedetector'; 3 4i18next.use(LanguageDetector).init({ 5 detection: { 6 order: ['querystring', 'cookie', 'localStorage', 'navigator'], 7 lookupQuerystring: 'lng', 8 lookupCookie: 'i18next', 9 caches: ['localStorage', 'cookie'], 10 }, 11});
Backend HTTP
Cargar traducciones desde el servidor:
JavaScript1import i18next from 'i18next'; 2import HttpBackend from 'i18next-http-backend'; 3 4i18next.use(HttpBackend).init({ 5 backend: { 6 loadPath: '/locales/{{lng}}/{{ns}}.json', 7 addPath: '/locales/add/{{lng}}/{{ns}}', 8 }, 9});
Backends Encadenados
Múltiples fuentes de respaldo:
JavaScript1import i18next from 'i18next'; 2import ChainedBackend from 'i18next-chained-backend'; 3import LocalStorageBackend from 'i18next-localstorage-backend'; 4import HttpBackend from 'i18next-http-backend'; 5 6i18next.use(ChainedBackend).init({ 7 backend: { 8 backends: [LocalStorageBackend, HttpBackend], 9 backendOptions: [ 10 { expirationTime: 7 * 24 * 60 * 60 * 1000 }, // 7 días 11 { loadPath: '/locales/{{lng}}/{{ns}}.json' }, 12 ], 13 }, 14});
Plugins Populares
| Plugin | Propósito |
|---|---|
| i18next-http-backend | Cargar desde servidor |
| i18next-localstorage-backend | Cachear en localStorage |
| i18next-browser-languagedetector | Detectar idioma del usuario |
| i18next-icu | Formato de mensaje ICU |
| i18next-intervalPlural-postProcessor | Plurales por intervalo |
Integración con Frameworks
React (react-i18next)
JSX1import { useTranslation } from 'react-i18next'; 2 3function Component() { 4 const { t } = useTranslation(); 5 return <h1>{t('welcome')}</h1>; 6}
Mira nuestra guía de react-i18next para más detalles.
Vue (vue-i18next)
VUE<template> <h1>{{ $t('welcome') }}</h1> </template>
Angular (angular-i18next)
TypeScript1@Component({ 2 template: `<h1>{{ 'welcome' | i18next }}</h1>` 3}) 4export class AppComponent {}
Node.js
JavaScript1import i18next from 'i18next'; 2import Backend from 'i18next-fs-backend'; 3 4await i18next.use(Backend).init({ 5 lng: 'en', 6 backend: { 7 loadPath: './locales/{{lng}}/{{ns}}.json', 8 }, 9}); 10 11console.log(i18next.t('greeting'));
Soporte TypeScript
Claves Type-Safe
TypeScript1// types/i18next.d.ts 2import 'i18next'; 3import en from '../locales/en/common.json'; 4 5declare module 'i18next' { 6 interface CustomTypeOptions { 7 defaultNS: 'common'; 8 resources: { 9 common: typeof en; 10 }; 11 } 12}
TypeScript1import i18next from 'i18next'; 2 3i18next.t('greeting'); // ✅ Autocompletado funciona 4i18next.t('nonexistent'); // ❌ Error TypeScript
Interpolación Tipada
TypeScript// Traducciones con variables son verificadas por tipo i18next.t('greeting', { name: 'John' }); // ✅ i18next.t('greeting', { wrong: 'var' }); // ❌ Error TypeScript
Mejores Prácticas de Producción
1. Organización de Archivos
src/
├── i18n/
│ ├── index.ts # config i18next
│ ├── types.d.ts # declaraciones TypeScript
│ └── locales/
│ ├── en/
│ │ ├── common.json
│ │ ├── auth.json
│ │ └── errors.json
│ └── es/
│ ├── common.json
│ ├── auth.json
│ └── errors.json
2. Convención de Nombres de Claves
JSON1{ 2 "page.section.element": "Valor", 3 "auth.login.title": "Iniciar Sesión", 4 "errors.validation.required": "Este campo es obligatorio", 5 "buttons.submit": "Enviar" 6}
3. Rastreo de Claves Faltantes
JavaScript1i18next.init({ 2 saveMissing: true, 3 missingKeyHandler: (lngs, ns, key, fallbackValue) => { 4 // Enviar a rastreo de errores 5 Sentry.captureMessage(`Clave i18n faltante: ${key}`); 6 7 // O loguear para extracción 8 console.warn(`[i18n] Falta: ${lngs.join(',')}/${ns}/${key}`); 9 }, 10});
4. Optimización de Rendimiento
JavaScript1i18next.init({ 2 // Solo cargar namespaces necesarios 3 ns: ['common'], 4 5 // Deshabilitar características innecesarias 6 initImmediate: false, 7 8 // Cachear en localStorage 9 backend: { 10 expirationTime: 7 * 24 * 60 * 60 * 1000, 11 }, 12}); 13 14// Pre-cargar namespaces críticos 15await i18next.loadNamespaces(['auth']);
5. Integración CI/CD
YAML1# .github/workflows/i18n.yml 2name: i18n Check 3on: [push] 4jobs: 5 check: 6 runs-on: ubuntu-latest 7 steps: 8 - uses: actions/checkout@v4 9 - name: Check missing translations 10 run: npx @intlpullhq/cli status --fail-on-missing
Escalando con IntlPull
Gestionar archivos JSON manualmente colapsa a escala. IntlPull se integra directamente con i18next:
Flujo de Trabajo CLI
Terminal1# Inicializar 2npx @intlpullhq/cli init 3 4# Extraer claves del código 5npx @intlpullhq/cli extract 6 7# Subir a IntlPull 8npx @intlpullhq/cli upload 9 10# Traducir con IA 11npx @intlpullhq/cli translate --target es,fr,de 12 13# Descargar traducciones 14npx @intlpullhq/cli download
Backend OTA
Actualizar traducciones sin desplegar:
JavaScript1import { IntlPullBackend } from '@intlpull/i18next-backend'; 2 3i18next.use(IntlPullBackend).init({ 4 backend: { 5 projectId: 'your-project', 6 apiKey: process.env.INTLPULL_API_KEY, 7 reloadOnSave: true, // Auto-refrescar cuando cambian las traducciones 8 }, 9});
Beneficios
| Característica | JSON Manual | IntlPull |
|---|---|---|
| Traducción IA | ❌ | ✅ GPT-4, Claude, DeepL |
| Colaboración en Equipo | ❌ | ✅ Comentarios, revisiones |
| Detección de Claves Faltantes | Manual | Automática |
| Actualizaciones OTA | ❌ | ✅ Sin despliegues |
| Memoria de Traducción | ❌ | ✅ Reutilizar traducciones |
Preguntas Frecuentes
¿Qué es i18next?
i18next es un framework de internacionalización de JavaScript que funciona en cualquier entorno—navegador, Node.js, React Native, Electron. Con 8M+ descargas semanales en npm, es la librería i18n más popular. Proporciona carga de traducciones, interpolación, pluralización, formateo y un sistema de plugins para backends personalizados y detección de idioma.
¿Cómo instalo i18next?
Instala con npm: npm install i18next. Para React, añade react-i18next. Para detección de idioma, añade i18next-browser-languagedetector. Para cargar desde servidor, añade i18next-http-backend. Inicializa con i18next.init({ lng: 'en', resources: {...} }).
¿Cuál es la diferencia entre i18next y react-i18next?
i18next es la librería central que funciona en cualquier entorno JavaScript. react-i18next es el binding oficial de React que proporciona hooks (useTranslation), componentes (Trans) y optimizaciones específicas de React. Usa i18next solo para Node.js o vanilla JS; usa react-i18next para apps React.
¿Cómo manejo la pluralización en i18next?
Usa sufijos plurales en claves de traducción: item_one, item_other, item_zero. Pasa count a la función t: t('item', { count: 5 }). i18next usa reglas plurales CLDR, por lo que idiomas complejos como el ruso (con formas _few, _many) funcionan automáticamente.
¿Cómo cargo traducciones desde un servidor?
Usa el plugin i18next-http-backend. Configura backend: { loadPath: '/locales/{{lng}}/{{ns}}.json' }. Las traducciones se obtienen bajo demanda basándose en el idioma y namespace actuales. Combina con i18next-localstorage-backend para caché.
¿Cómo detecto el idioma del usuario automáticamente?
Usa el plugin i18next-browser-languagedetector. Configura el orden de detección: order: ['querystring', 'cookie', 'localStorage', 'navigator']. Verifica parámetros URL, cookies, localStorage y configuración del navegador para determinar el mejor idioma.
¿Puedo usar i18next con TypeScript?
Sí, i18next tiene excelente soporte TypeScript. Crea un archivo de declaración de tipos importando tu JSON de traducción y extiende CustomTypeOptions. Obtienes autocompletado y errores en tiempo de compilación para claves inválidas. Esto atrapa errores tipográficos antes del tiempo de ejecución.
¿Cómo uso namespaces en i18next?
Los namespaces dividen las traducciones en grupos lógicos como 'common', 'auth', 'dashboard'. Configura ns: ['common', 'auth'] y accede con t('auth:login') o establece defaultNS para evitar prefijos. Carga namespaces bajo demanda con loadNamespaces().
¿Qué plugins están disponibles para i18next?
Existen 50+ plugins para varias necesidades: i18next-http-backend (carga servidor), i18next-localstorage-backend (caché), i18next-browser-languagedetector (detección), i18next-icu (formato ICU), y bindings de framework para React, Vue, Angular, Svelte. Revisa la lista oficial de plugins.
¿Cómo manejo traducciones faltantes?
Configura missingKeyHandler para loguear o reportar claves faltantes: missingKeyHandler: (lng, ns, key) => console.warn(Falta: ${key}). Usa saveMissing: true en desarrollo para rastrear lo que necesita traducción. IntlPull puede detectar y crear automáticamente claves faltantes.
Resumen
i18next es el framework de internacionalización de JavaScript estándar de la industria:
| Aspecto | Detalles |
|---|---|
| Instalación | npm install i18next |
| Función Principal | i18next.t('key') |
| Interpolación | Sintaxis {{variable}} |
| Plurales | Sufijos _one, _other |
| Namespaces | Agrupación lógica |
| Detección | Navegador, URL, cookie |
| TypeScript | Seguridad de tipos completa |
| Frameworks | React, Vue, Angular, Node |
Para apps de producción, combina i18next con IntlPull para obtener traducción IA, actualizaciones OTA y colaboración en equipo sin gestionar archivos JSON manualmente.
¿Listo para simplificar tu i18n? Comienza gratis con IntlPull — funciona perfectamente con cualquier configuración i18next.
