Установка angular-i18next

В экосистеме Angular интеграция интернационализации через i18next требует корректной установки ядра библиотеки, адаптера Angular и вспомогательных модулей, обеспечивающих загрузку ресурсов, определение языка пользователя и реактивное обновление переводов в компонентах.

Основой выступает библиотека i18next, отвечающая за управление переводами, форматирование и переключение языков.

npm install i18next

Для работы в браузере обычно добавляются плагины, расширяющие функциональность:

npm install i18next-http-backend i18next-browser-languagedetector
  • i18next-http-backend — загрузка переводов по HTTP (JSON-файлы с сервера или из assets)
  • i18next-browser-languagedetector — автоматическое определение языка пользователя

Установка Angular-адаптера

В Angular-интеграциях i18next используется связующий слой, обеспечивающий реактивность и DI-интеграцию.

npm install angular-i18next

Пакет предоставляет сервисы и директивы, позволяющие использовать переводы внутри компонентов Angular без прямого обращения к API i18next.

Дополнительные типы для TypeScript

При использовании TypeScript требуется установка типов:

npm install --save-dev @types/i18next

Это обеспечивает корректную типизацию методов t(), конфигурации и языковых ресурсов.

Инициализация i18next в Angular-приложении

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

import i18next from 'i18next';
import Backend from 'i18next-http-backend';
import LanguageDetector from 'i18next-browser-languagedetector';

i18next
  .use(Backend)
  .use(LanguageDetector)
  .init({
    fallbackLng: 'en',
    debug: false,
    interpolation: {
      escapeValue: false
    },
    backend: {
      loadPath: '/assets/locales/{{lng}}/{{ns}}.json'
    }
  });

Ключевым элементом является параметр loadPath, определяющий структуру хранения переводов в проекте Angular.

Подключение angular-i18next в модуле приложения

После установки адаптера необходимо зарегистрировать его в корневом модуле Angular.

import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { I18NextModule, I18NEXT_SERVICE } from 'angular-i18next';

import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    I18NextModule.forRoot()
  ],
  providers: [
    {
      provide: I18NEXT_SERVICE,
      useValue: i18next
    }
  ],
  bootstrap: [AppComponent]
})
export class AppModule {}

Передача экземпляра i18next через I18NEXT_SERVICE позволяет всем компонентам Angular использовать единый экземпляр конфигурации.

Структура файлов переводов

Организация локалей влияет на масштабируемость приложения.

assets/
  locales/
    en/
      common.json
      auth.json
    ru/
      common.json
      auth.json

Файлы разбиваются по пространствам имен (namespaces), что уменьшает нагрузку на загрузку и упрощает поддержку.

Пример содержимого common.json:

{
  "welcome": "Добро пожаловать",
  "logout": "Выйти"
}

Использование сервиса перевода в компонентах

После настройки доступ к функциям i18next осуществляется через сервис адаптера.

import { Component } from '@angular/core';
import { ITranslationService, I18NEXT_SERVICE } from 'angular-i18next';
import { Inject } from '@angular/core';

@Component({
  selector: 'app-header',
  template: `
    <h1>{{ title }}</h1>
    <button (click)="switchLanguage('ru')">RU</button>
    <button (click)="switchLanguage('en')">EN</button>
  `
})
export class HeaderComponent {
  title = '';

  constructor(
    @Inject(I18NEXT_SERVICE) private i18next: ITranslationService
  ) {
    this.title = this.i18next.t('common:welcome');
  }

  switchLanguage(lang: string) {
    this.i18next.changeLanguage(lang);
  }
}

Метод t() выполняет извлечение перевода, учитывая namespace и текущий язык.

Директивы для шаблонов Angular

Библиотека предоставляет директивный способ работы с переводами без необходимости обращаться к сервису напрямую.

<h2 [i18next]="'common:welcome'"></h2>

Также поддерживается реактивное обновление при смене языка без перезагрузки компонента.

Обновление языка на уровне приложения

Смена языка влияет на все активные компоненты через общий экземпляр i18next.

this.i18next.changeLanguage('ru');

После вызова происходит:

  • перезагрузка переводов при необходимости
  • обновление подписанных компонентов
  • повторная интерполяция строк

Интерполяция и параметры

i18next поддерживает динамические значения в переводах.

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

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

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

Интерполяция обрабатывается на уровне библиотеки и не требует дополнительной логики в Angular.

Ленивая загрузка переводов

При больших приложениях важно избегать загрузки всех языков сразу. Использование backend-плагина позволяет загружать файлы по требованию.

backend: {
  loadPath: '/assets/locales/{{lng}}/{{ns}}.json'
}

Механизм подстановки {{lng}} и {{ns}} позволяет гибко управлять структурой хранения.

Обработка отсутствующих переводов

При отсутствии ключа используется fallback-язык или возвращается сам ключ.

i18next.init({
  fallbackLng: 'en',
  saveMissing: true
});

Опция saveMissing может использоваться для логирования недостающих переводов в систему сбора ошибок.

Синхронизация с Angular жизненным циклом

Angular не всегда автоматически отслеживает изменения i18next, поэтому важно учитывать Change Detection.

При необходимости принудительного обновления используется ChangeDetectorRef:

constructor(private cdr: ChangeDetectorRef) {}

ngOnInit() {
  this.i18next.on('languageChanged', () => {
    this.cdr.detectChanges();
  });
}

Это гарантирует актуальность интерфейса при переключении языка.

Множественные namespaces

Разделение переводов по модулям Angular облегчает масштабирование:

this.i18next.t('auth:loginButton');
this.i18next.t('profile:title');

Каждый namespace загружается отдельно, что снижает начальную нагрузку приложения.

Поддержка множественного числа

i18next поддерживает правила плюрализации для различных языков.

{
  "item": "{{count}} элемент",
  "item_plural": "{{count}} элементов"
}

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

this.i18next.t('common:item', { count: 5 });

Выбор формы выполняется автоматически на основе правил языка.

Форматирование и контекст

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

{
  "friend_male": "друг",
  "friend_female": "подруга"
}
this.i18next.t('common:friend', { context: 'female' });

Интеграция с Angular сервисами

Для более сложной архитектуры i18next часто инкапсулируется в собственный сервис-обёртку:

@Injectable({ providedIn: 'root' })
export class TranslationFacade {
  constructor(@Inject(I18NEXT_SERVICE) private i18next: ITranslationService) {}

  translate(key: string, params?: any) {
    return this.i18next.t(key, params);
  }
}

Такой подход снижает связанность компонентов с конкретной реализацией библиотеки.

Отладка конфигурации

В режиме разработки полезно включать debug-режим:

i18next.init({
  debug: true
});

Он выводит информацию о загрузке ресурсов, отсутствии ключей и процессе интерполяции.

Производственные особенности установки

При сборке Angular-приложения важно учитывать:

  • корректную настройку assets для локалей
  • исключение лишних языков из бандла
  • предварительную загрузку дефолтного языка
  • кэширование JSON-файлов переводов

Структура конфигурации Angular CLI:

"assets": [
  "src/favicon.ico",
  "src/assets"
]

Эта настройка обеспечивает доступ к /assets/locales после сборки.

Использование с SSR (Angular Universal)

При серверном рендеринге необходимо синхронизировать язык на сервере и клиенте. Для этого передаётся начальное состояние:

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

Серверная инициализация предотвращает гидрационные расхождения между HTML и клиентским состоянием.