IntlPull
Guide
20 min read

i18next: La guía completa del marco de internacionalización para 2026

Domine i18next, el framework JavaScript i18n más popular. Guía completa que cubre configuración, plugins, espacios de nombres, interpolación y mejores prácticas de producción.

IntlPull Team
IntlPull Team
03 Feb 2026, 11:44 AM [PST]
On this page
Summary

Domine i18next, el framework JavaScript i18n más popular. Guía completa que cubre configuración, plugins, espacios de nombres, interpolación y mejores prácticas de producción.

Respuesta rápida

i18next es el framework de internacionalización de JavaScript más popular con más de 8M de descargas npm semanales. Instalar con npm install i18next, configure with i18n.init({ lng: 'en', resources: {...} }), then call i18n.t('key') to translate. It works in any JavaScript environment—React, Vue, Node.js, vanilla JS, mobile apps. For production, combine with IntlPull for AI-powered translation management and team collaboration.


What is i18next?

i18next is a framework-agnostic internationalization (i18n) library for JavaScript. Created in 2011, it's the most battle-tested i18n solution with:

  • Universal support: Browser, Node.js, React Native, Electron, Deno
  • Framework bindings: React, Vue, Angular, Svelte, Next.js
  • Plugin ecosystem: 50+ plugins for backends, detection, caching
  • Enterprise-ready: Used by companies like Microsoft, Adobe, Airbnb

Why i18next?

Featurei18nextOther Libraries
Weekly Downloads8M+Varies
First Release2011Varies
Framework SupportAllOften limited
Plugin SystemExtensiveLimited
CommunityLargestSmaller
TypeScriptExcellentVaries
MaintenanceActiveVaries

Core Concepts

1. Translation Files (Resources)

Translations are organized as JSON objects with nested keys:

JSON
1{
2  "greeting": "Hello!",
3  "nav": {
4    "home": "Home",
5    "about": "About Us"
6  },
7  "buttons": {
8    "submit": "Submit",
9    "cancel": "Cancel"
10  }
11}

2. Namespaces

Namespaces split translations into logical groups (like code modules):

locales/
├── en/
│   ├── common.json    # Shared strings
│   ├── auth.json      # Authentication
│   └── dashboard.json # Dashboard page
└── es/
    ├── common.json
    ├── auth.json
    └── dashboard.json

3. Language Detection

i18next can detect user language from multiple sources:

  • URL parameter (?lng=es)
  • Cookie
  • localStorage
  • Browser settings
  • HTML lang attribute

4. Fallback Chain

When a translation is missing:

  1. Check requested language (es-MX)
  2. Check parent language (es)
  3. Check fallback language (en)
  4. Return key or default value

Basic Setup

Installation

Terminal
1npm install i18next
2# or
3yarn add i18next
4# or
5pnpm add i18next

Minimal Configuration

JavaScript
1import 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// Use translations
22console.log(i18next.t('greeting')); // "Hello, World!"

Full Configuration

JavaScript
1import i18next from 'i18next';
2
3i18next.init({
4  // Language settings
5  lng: 'en',                    // Current language
6  fallbackLng: 'en',            // Fallback when translation missing
7  supportedLngs: ['en', 'es', 'fr', 'de'],
8  load: 'languageOnly',         // 'en' instead of 'en-US'
9
10  // Namespace settings
11  ns: ['common', 'auth', 'dashboard'],
12  defaultNS: 'common',
13
14  // Resources (inline or loaded via backend)
15  resources: {
16    en: { common: {...}, auth: {...} },
17    es: { common: {...}, auth: {...} },
18  },
19
20  // Interpolation
21  interpolation: {
22    escapeValue: false,         // Not needed for React
23    formatSeparator: ',',
24  },
25
26  // Key settings
27  keySeparator: '.',            // For nested keys
28  nsSeparator: ':',             // namespace:key
29
30  // Missing keys
31  saveMissing: true,
32  missingKeyHandler: (lng, ns, key) => {
33    console.warn(`Missing: ${lng}/${ns}/${key}`);
34  },
35
36  // Debug
37  debug: process.env.NODE_ENV === 'development',
38});

Variable Interpolation

Basic Variables

JSON
1{
2  "greeting": "Hello, {{name}}!",
3  "cartInfo": "You have {{count}} items worth {{total}}"
4}
JavaScript
1i18next.t('greeting', { name: 'John' });
2// "Hello, John!"
3
4i18next.t('cartInfo', { count: 5, total: '$99.99' });
5// "You have 5 items worth $99.99"

Nested Objects

JSON
{
  "userInfo": "{{user.name}} ({{user.email}})"
}
JavaScript
1i18next.t('userInfo', {
2  user: { name: 'John', email: 'john@example.com' }
3});
4// "John (john@example.com)"

Default Values

JavaScript
1i18next.t('unknown.key', 'Default text');
2// "Default text" (when key doesn't exist)
3
4i18next.t('greeting', { name: 'Guest', defaultValue: 'Hello!' });
5// Uses defaultValue if key is missing

Formatting

JSON
1{
2  "price": "Total: {{amount, currency}}",
3  "date": "Created: {{date, datetime}}"
4}
JavaScript
1i18next.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"

Pluralization

Basic Plurals

JSON
1{
2  "item_one": "{{count}} item",
3  "item_other": "{{count}} items"
4}
JavaScript
i18next.t('item', { count: 1 });  // "1 item"
i18next.t('item', { count: 5 });  // "5 items"

Zero Count

JSON
1{
2  "item_zero": "No items",
3  "item_one": "{{count}} item",
4  "item_other": "{{count}} items"
5}

Complex Plurals

Languages like Russian and Arabic have complex plural rules:

JSON
1{
2  "item_zero": "нет товаров",
3  "item_one": "{{count}} товар",
4  "item_few": "{{count}} товара",
5  "item_many": "{{count}} товаров",
6  "item_other": "{{count}} товаров"
7}

i18next automatically selects the correct form based on CLDR plural rules.

Ordinals

JSON
1{
2  "rank_ordinal_one": "{{count}}st",
3  "rank_ordinal_two": "{{count}}nd",
4  "rank_ordinal_few": "{{count}}rd",
5  "rank_ordinal_other": "{{count}}th"
6}
JavaScript
1i18next.t('rank', { count: 1, ordinal: true });  // "1st"
2i18next.t('rank', { count: 22, ordinal: true }); // "22nd"
3i18next.t('rank', { count: 33, ordinal: true }); // "33rd"
4i18next.t('rank', { count: 44, ordinal: true }); // "44th"

Context

Same key, different translations based on context:

JSON
1{
2  "friend": "A friend",
3  "friend_male": "A boyfriend",
4  "friend_female": "A girlfriend"
5}
JavaScript
i18next.t('friend');                        // "A friend"
i18next.t('friend', { context: 'male' });   // "A boyfriend"
i18next.t('friend', { context: 'female' }); // "A girlfriend"

Combining Context with Plurals

JSON
1{
2  "friend_male_one": "{{count}} boyfriend",
3  "friend_male_other": "{{count}} boyfriends",
4  "friend_female_one": "{{count}} girlfriend",
5  "friend_female_other": "{{count}} girlfriends"
6}
JavaScript
i18next.t('friend', { context: 'male', count: 2 });
// "2 boyfriends"

Namespaces

Loading Multiple Namespaces

JavaScript
1i18next.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');           // From common (default)
14i18next.t('auth:login');       // From auth namespace
15i18next.t('dashboard:title');  // From dashboard namespace

Dynamic Namespace Loading

JavaScript
1// Load namespace on demand
2await i18next.loadNamespaces('settings');
3
4// Check if namespace is loaded
5i18next.hasLoadedNamespace('settings');

Plugin System

Language Detection

JavaScript
1import 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});

HTTP Backend

Load translations from server:

JavaScript
1import 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});

Chained Backends

Multiple fallback sources:

JavaScript
1import 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 days
11      { loadPath: '/locales/{{lng}}/{{ns}}.json' },
12    ],
13  },
14});
PluginPurpose
i18next-http-backendLoad from server
i18next-localstorage-backendCache in localStorage
i18next-browser-languagedetectorDetect user language
i18next-icuICU message format
i18next-intervalPlural-postProcessorInterval plurals

Framework Integration

React (react-i18next)

JSX
1import { useTranslation } from 'react-i18next';
2
3function Component() {
4  const { t } = useTranslation();
5  return <h1>{t('welcome')}</h1>;
6}

See our react-i18next guide for details.

Vue (vue-i18next)

VUE
<template>
  <h1>{{ $t('welcome') }}</h1>
</template>

Angular (angular-i18next)

TypeScript
1@Component({
2  template: `<h1>{{ 'welcome' | i18next }}</h1>`
3})
4export class AppComponent {}

Node.js

JavaScript
1import 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'));

TypeScript Support

Type-Safe Keys

TypeScript
1// 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}
TypeScript
1import i18next from 'i18next';
2
3i18next.t('greeting');    // ✅ Autocomplete works
4i18next.t('nonexistent'); // ❌ TypeScript error

Typed Interpolation

TypeScript
// Translations with variables are type-checked
i18next.t('greeting', { name: 'John' }); // ✅
i18next.t('greeting', { wrong: 'var' }); // ❌ TypeScript error

Production Best Practices

1. File Organization

src/
├── i18n/
│   ├── index.ts           # i18next config
│   ├── types.d.ts         # TypeScript declarations
│   └── locales/
│       ├── en/
│       │   ├── common.json
│       │   ├── auth.json
│       │   └── errors.json
│       └── es/
│           ├── common.json
│           ├── auth.json
│           └── errors.json

2. Key Naming Convention

JSON
1{
2  "page.section.element": "Value",
3  "auth.login.title": "Sign In",
4  "errors.validation.required": "This field is required",
5  "buttons.submit": "Submit"
6}

3. Missing Key Tracking

JavaScript
1i18next.init({
2  saveMissing: true,
3  missingKeyHandler: (lngs, ns, key, fallbackValue) => {
4    // Send to error tracking
5    Sentry.captureMessage(`Missing i18n key: ${key}`);
6
7    // Or log for extraction
8    console.warn(`[i18n] Missing: ${lngs.join(',')}/${ns}/${key}`);
9  },
10});

4. Performance Optimization

JavaScript
1i18next.init({
2  // Only load needed namespaces
3  ns: ['common'],
4
5  // Disable unneeded features
6  initImmediate: false,
7
8  // Cache in localStorage
9  backend: {
10    expirationTime: 7 * 24 * 60 * 60 * 1000,
11  },
12});
13
14// Preload critical namespaces
15await i18next.loadNamespaces(['auth']);

5. CI/CD Integration

YAML
1# .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

Scaling with IntlPull

Managing JSON files manually breaks down at scale. IntlPull integrates directly with i18next:

CLI Workflow

Terminal
1# Initialize
2npx @intlpullhq/cli init
3
4# Extract keys from code
5npx @intlpullhq/cli extract
6
7# Upload to IntlPull
8npx @intlpullhq/cli upload
9
10# Translate with AI
11npx @intlpullhq/cli translate --target es,fr,de
12
13# Download translations
14npx @intlpullhq/cli download

OTA Backend

Update translations without deploying:

JavaScript
1import { 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-refresh when translations change
8  },
9});

Benefits

FeatureManual JSONIntlPull
AI Translation✅ GPT-4, Claude, DeepL
Team Collaboration✅ Comments, reviews
Missing Key DetectionManualAutomatic
OTA Updates✅ No deploys
Translation Memory✅ Reuse translations

Frequently Asked Questions

What is i18next?

i18next is a JavaScript internationalization framework that works in any environment—browser, Node.js, React Native, Electron. With 8M+ weekly npm downloads, it's the most popular i18n library. It provides translation loading, interpolation, pluralization, formatting, and a plugin system for custom backends and language detection.

How do I install i18next?

Install with npm: npm install i18next. For React, add react-i18next. For language detection, add i18next-browser-languagedetector. For loading from server, add i18next-http-backend. Initialize with i18next.init({ lng: 'en', resources: {...} }).

What is the difference between i18next and react-i18next?

i18next is the core library that works in any JavaScript environment. react-i18next is the official React binding that provides hooks (useTranslation), components (Trans), and React-specific optimizations. Use i18next alone for Node.js or vanilla JS; use react-i18next for React apps.

How do I handle pluralization in i18next?

Use plural suffixes on translation keys: item_one, item_other, item_zero. Pass count to the t function: t('item', { count: 5 }). i18next uses CLDR plural rules, so complex languages like Russian (with _few, _many forms) work automatically.

How do I load translations from a server?

Use i18next-http-backend plugin. Configure backend: { loadPath: '/locales/{{lng}}/{{ns}}.json' }. Translations are fetched on demand based on current language and namespace. Combine with i18next-localstorage-backend for caching.

How do I detect user language automatically?

Use i18next-browser-languagedetector plugin. Configure detection order: order: ['querystring', 'cookie', 'localStorage', 'navigator']. It checks URL params, cookies, localStorage, and browser settings to determine the best language.

Can I use i18next with TypeScript?

Yes, i18next has excellent TypeScript support. Create a type declaration file importing your translation JSON, and extend CustomTypeOptions. You get autocomplete and compile-time errors for invalid keys. This catches typos before runtime.

How do I use namespaces in i18next?

Namespaces split translations into logical groups like 'common', 'auth', 'dashboard'. Configure ns: ['common', 'auth'] and access with t('auth:login') or set defaultNS to avoid prefixes. Load namespaces on demand with loadNamespaces().

What plugins are available for i18next?

50+ plugins exist for various needs: i18next-http-backend (server loading), i18next-localstorage-backend (caching), i18next-browser-languagedetector (detection), i18next-icu (ICU format), and framework bindings for React, Vue, Angular, Svelte. Check the official plugin list.

How do I handle missing translations?

Configure missingKeyHandler to log or report missing keys: missingKeyHandler: (lng, ns, key) => console.warn(\Missing: ${key}`). Use saveMissing: true` in development to track what needs translation. IntlPull can automatically detect and create missing keys.

Summary

i18next is the industry-standard JavaScript internationalization framework:

AspectDetails
Installationnpm install i18next
Core Functioni18next.t('key')
Interpolation{{variable}} syntax
Plurals_one, _other suffixes
NamespacesLogical grouping
DetectionBrowser, URL, cookie
TypeScriptFull type safety
FrameworksReact, Vue, Angular, Node

For production apps, combine i18next with IntlPull to get AI translation, OTA updates, and team collaboration without managing JSON files manually.

Ready to simplify your i18n? Start free with IntlPull — works seamlessly with any i18next setup.

Tags
i18next
i18n
javascript
internationalization
localization
tutorial
2026
IntlPull Team
IntlPull Team
Engineering

Building tools to help teams ship products globally. Follow us for more insights on localization and i18n.