Минимальная конфигурация для старта

I18next распространяется как независимая библиотека интернационализации для JavaScript-приложений. Базовая установка выполняется через npm:

npm install i18next

Для браузерного окружения без сборщика доступно подключение через CDN:

<script src="https://unpkg.com/i18next/dist/umd/i18next.min.js"></script>

После установки глобальный объект i18next становится доступным для конфигурации и перевода строк.


Минимальная структура проекта

Простейшая структура проекта с поддержкой локализации обычно выглядит следующим образом:

project/
├── index.js
├── locales/
│   ├── en/
│   │   └── translation.json
│   └── ru/
│       └── translation.json
└── package.json

Каталог locales содержит переводы для каждого языка. Файл translation.json является стандартным namespace по умолчанию.


Первый файл перевода

Пример английской локализации:

{
  "welcome": "Welcome",
  "description": "Internationalization example"
}

Русская локализация:

{
  "welcome": "Добро пожаловать",
  "description": "Пример интернационализации"
}

Ключи должны совпадать между всеми языками. Изменяется только текст перевода.


Базовая инициализация

Минимальная конфигурация I18next может быть выполнена прямо в основном файле приложения.

import i18next from 'i18next';

i18next.init({
  lng: 'ru',
  resources: {
    en: {
      translation: {
        welcome: 'Welcome'
      }
    },
    ru: {
      translation: {
        welcome: 'Добро пожаловать'
      }
    }
  }
});

console.log(i18next.t('welcome'));

Результат:

Добро пожаловать

Разбор минимальной конфигурации

Свойство lng

Определяет активный язык приложения.

lng: 'ru'

Если установить:

lng: 'en'

то метод t() начнёт возвращать английские строки.


Свойство resources

Содержит словари переводов.

Структура:

resources: {
  язык: {
    namespace: {
      ключ: значение
    }
  }
}

Пример:

resources: {
  en: {
    translation: {
      hello: 'Hello'
    }
  }
}
  • en — код языка
  • translation — namespace
  • hello — ключ
  • Hello — перевод

Метод t()

Главная функция библиотеки.

i18next.t('welcome');

Метод ищет ключ в активной локали и возвращает перевод.


Минимальная конфигурация с внешними JSON-файлами

Хранение переводов внутри init() подходит только для демонстраций. В реальных проектах переводы выносятся в отдельные файлы.

Подключение JSON

import i18next from 'i18next';

import en from './locales/en/translation.json';
import ru from './locales/ru/translation.json';

i18next.init({
  lng: 'ru',
  resources: {
    en: {
      translation: en
    },
    ru: {
      translation: ru
    }
  }
});

Такой подход:

  • упрощает поддержку;
  • уменьшает размер конфигурации;
  • позволяет масштабировать проект;
  • делает переводы независимыми от кода.

Использование fallback-языка

Fallback-язык используется, если перевод отсутствует в текущей локали.

i18next.init({
  lng: 'ru',
  fallbackLng: 'en',
  resources: {
    en: {
      translation: {
        title: 'Home page'
      }
    },
    ru: {
      translation: {}
    }
  }
});

Вызов:

i18next.t('title');

вернёт:

Home page

поскольку ключ отсутствует в русском словаре.


Namespace по умолчанию

Если namespace не указан явно, I18next использует translation.

resources: {
  ru: {
    translation: {
      hello: 'Привет'
    }
  }
}

Обращение к ключу:

i18next.t('hello');

Если используется другой namespace:

resources: {
  ru: {
    common: {
      hello: 'Привет'
    }
  }
}

то потребуется указание namespace:

i18next.t('common:hello');

Асинхронная инициализация

Метод init() возвращает Promise.

Современный вариант инициализации:

import i18next from 'i18next';

await i18next.init({
  lng: 'ru',
  resources: {
    ru: {
      translation: {
        hello: 'Привет'
      }
    }
  }
});

console.log(i18next.t('hello'));

Такой подход особенно важен при загрузке переводов с сервера.


Переключение языка

Язык можно менять во время работы приложения.

i18next.changeLanguage('en');

После переключения:

console.log(i18next.t('welcome'));

вернёт английский перевод.


Проверка текущего языка

Активный язык хранится в свойстве language.

console.log(i18next.language);

Результат:

ru

Вложенные ключи

I18next поддерживает древовидную структуру переводов.

JSON

{
  "menu": {
    "home": "Главная",
    "about": "О нас"
  }
}

Использование

i18next.t('menu.home');

Результат:

Главная

Такой подход помогает структурировать большие словари.


Интерполяция значений

Минимальная конфигурация уже поддерживает подстановку переменных.

Перевод

{
  "welcome": "Привет, {{name}}"
}

Использование

i18next.t('welcome', {
  name: 'Алексей'
});

Результат:

Привет, Алексей

Экранирование HTML

По умолчанию I18next экранирует HTML-символы для защиты от XSS.

Настройка:

interpolation: {
  escapeValue: true
}

Во frontend-фреймворках вроде React экранирование часто отключают:

interpolation: {
  escapeValue: false
}

React самостоятельно защищает DOM от большинства XSS-атак.


Минимальная конфигурация для Node.js

Простейший пример для серверного Jav * aScript:

import i18next from 'i18next';

await i18next.init({
  lng: 'ru',
  resources: {
    ru: {
      translation: {
        error: 'Ошибка сервера'
      }
    }
  }
});

console.log(i18next.t('error'));

I18next одинаково работает:

  • в браузере;
  • в Node.js;
  • в React;
  • в Vue;
  • в Express;
  • в Next.js.

Инициализация через callback

Старый вариант конфигурации использует callback-функцию.

i18next.init({
  lng: 'ru',
  resources: {
    ru: {
      translation: {
        hello: 'Привет'
      }
    }
  }
}, (err, t) => {
  console.log(t('hello'));
});

Такой стиль встречается в старых проектах и legacy-коде.


Использование нескольких языков

Минимальная конфигурация может содержать сразу несколько локалей.

i18next.init({
  lng: 'en',
  resources: {
    en: {
      translation: {
        save: 'Save'
      }
    },
    ru: {
      translation: {
        save: 'Сохранить'
      }
    },
    de: {
      translation: {
        save: 'Speichern'
      }
    }
  }
});

Отладка переводов

Для диагностики можно включить режим debug.

i18next.init({
  debug: true,
  lng: 'ru',
  resources: {}
});

I18next начнёт выводить информацию в консоль:

  • загрузку ресурсов;
  • поиск ключей;
  • ошибки namespace;
  • отсутствующие переводы.

Поведение при отсутствии ключа

Если ключ отсутствует:

i18next.t('unknown_key');

по умолчанию возвращается сам ключ:

unknown_key

Это помогает быстро замечать пропущенные переводы.


Отключение возврата ключей

Можно изменить поведение:

i18next.init({
  returnNull: false,
  returnEmptyString: false
});

Такая настройка предотвращает возврат null и пустых строк.


Минимальная конфигурация с автоматическим определением языка

Для браузеров часто используется плагин определения языка пользователя.

Установка:

npm install i18next-browser-languagedetector

Подключение:

import i18next from 'i18next';
import LanguageDetector from 'i18next-browser-languagedetector';

i18next
  .use(LanguageDetector)
  .init({
    fallbackLng: 'en',
    resources: {
      en: {
        translation: {
          hello: 'Hello'
        }
      },
      ru: {
        translation: {
          hello: 'Привет'
        }
      }
    }
  });

Плагин анализирует:

  • язык браузера;
  • cookie;
  • localStorage;
  • параметры URL;
  • настройки пользователя.

Минимальная конфигурация для React

В React обычно используется пакет react-i18next.

Установка:

npm install react-i18next

Конфигурация:

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

i18next
  .use(initReactI18next)
  .init({
    lng: 'ru',
    fallbackLng: 'en',
    resources: {
      en: {
        translation: {
          hello: 'Hello'
        }
      },
      ru: {
        translation: {
          hello: 'Привет'
        }
      }
    }
  });

Использование в компоненте:

import { useTranslation } from 'react-i18next';

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

  return <h1>{t('hello')}</h1>;
}

Типичная стартовая конфигурация

Практический минимальный шаблон:

import i18next from 'i18next';

import en from './locales/en/translation.json';
import ru from './locales/ru/translation.json';

await i18next.init({
  lng: 'ru',
  fallbackLng: 'en',

  resources: {
    en: {
      translation: en
    },
    ru: {
      translation: ru
    }
  },

  interpolation: {
    escapeValue: false
  }
});

Такая конфигурация уже подходит для:

  • небольших frontend-приложений;
  • серверных API;
  • React-проектов;
  • Vue/Nuxt;
  • Next.js;
  • Electron-приложений;
  • SPA-интерфейсов;
  • административных панелей.