Home » Интернационализация в Angular: как локализовать приложение
Интернационализация в Angular: как локализовать приложение

Интернационализация в Angular: как локализовать приложение

Если ты разрабатываешь приложения на Angular и тебе нужно поддерживать несколько языков, то без интернационализации (i18n) не обойтись. Это не просто перевод текста — это полноценная локализация, которая включает форматирование дат, чисел, валют и даже направление текста. Сегодня разберём, как правильно настроить i18n в Angular, какие подводные камни ждут и как развернуть многоязычное приложение на своём сервере.

Как работает интернационализация в Angular

Angular i18n работает на этапе компиляции. Это значит, что для каждого языка генерируется отдельный бандл приложения. Никаких рантайм-переключений языков — всё статично и быстро.

Основные компоненты системы:

  • @angular/localize — основная библиотека для локализации
  • Angular CLI — инструменты для извлечения и сборки переводов
  • XLIFF, XMB, JSON — форматы файлов переводов
  • ICU expressions — для сложных случаев (множественные формы, условия)

Пошаговая настройка локализации

Начнём с чистого проекта. Если у тебя уже есть приложение, просто пропусти создание нового.

ng new my-i18n-app
cd my-i18n-app
ng add @angular/localize

Теперь настраиваем angular.json для поддержки нескольких языков:

{
  "projects": {
    "my-i18n-app": {
      "i18n": {
        "sourceLocale": "en",
        "locales": {
          "ru": "src/locale/messages.ru.xlf",
          "de": "src/locale/messages.de.xlf"
        }
      },
      "architect": {
        "build": {
          "configurations": {
            "ru": {
              "aot": true,
              "outputPath": "dist/ru/",
              "i18nFile": "src/locale/messages.ru.xlf",
              "i18nFormat": "xlf",
              "i18nLocale": "ru"
            },
            "de": {
              "aot": true,
              "outputPath": "dist/de/",
              "i18nFile": "src/locale/messages.de.xlf",
              "i18nFormat": "xlf",
              "i18nLocale": "de"
            }
          }
        }
      }
    }
  }
}

Добавляем переводы в компонент:

// app.component.html
<h1 i18n="@@welcome">Welcome to our app!</h1>
<p i18n="@@description">This is a multilingual application</p>

<div i18n="@@user-count">
  {users, plural, =0 {No users} =1 {One user} other {{{users}} users}}
</div>

Извлекаем строки для перевода:

ng extract-i18n
ng extract-i18n --output-path src/locale

Практические примеры и кейсы

Вот несколько реальных сценариев, с которыми столкнётся каждый разработчик:

Работа с датами и числами

// В компоненте
export class AppComponent {
  today = new Date();
  price = 1234.56;
  users = 42;
}
<!-- В шаблоне -->
<p>{{ today | date:'medium' }}</p>
<p>{{ price | currency:'USD':'symbol':'1.2-2' }}</p>
<p>{{ users | number:'1.0-0' }}</p>

Условные переводы с ICU expressions

<span i18n="@@user-greeting">
  {gender, select, 
    male {Welcome, sir!} 
    female {Welcome, madam!} 
    other {Welcome!}
  }
</span>

Атрибуты и плейсхолдеры

<input 
  type="text" 
  i18n-placeholder="@@search-placeholder" 
  placeholder="Search..."
  i18n-title="@@search-title"
  title="Enter search term"
/>

Сравнение подходов к интернационализации

Подход Производительность Гибкость Сложность настройки Размер бандла
Angular i18n Отличная Средняя Высокая Оптимальный
ngx-translate Хорошая Высокая Низкая Больше на 20-30%
Transloco Хорошая Высокая Средняя Средний

Автоматизация и скрипты

Создаём скрипты для автоматической сборки всех языков:

# build-i18n.sh
#!/bin/bash

languages=("en" "ru" "de")

for lang in "${languages[@]}"
do
  echo "Building $lang..."
  if [ "$lang" == "en" ]; then
    ng build --configuration=production
  else
    ng build --configuration=production,$lang
  fi
done

echo "All languages built successfully!"

Для автоматического развёртывания на сервере:

# deploy-i18n.sh
#!/bin/bash

# Собираем все языки
./build-i18n.sh

# Создаём структуру папок на сервере
ssh user@your-server "mkdir -p /var/www/myapp/{en,ru,de}"

# Загружаем файлы
scp -r dist/en/* user@your-server:/var/www/myapp/en/
scp -r dist/ru/* user@your-server:/var/www/myapp/ru/
scp -r dist/de/* user@your-server:/var/www/myapp/de/

echo "Deployment completed!"

Настройка веб-сервера для многоязычности

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

server {
    listen 80;
    server_name myapp.com;
    root /var/www/myapp;
    index index.html;

    # Определяем язык по Accept-Language
    location / {
        set $lang "en";
        if ($http_accept_language ~* "^ru") {
            set $lang "ru";
        }
        if ($http_accept_language ~* "^de") {
            set $lang "de";
        }
        
        # Перенаправляем на соответствующую папку
        try_files $uri $uri/ /$lang/index.html;
    }

    # Прямые пути к языковым версиям
    location /en/ {
        try_files $uri $uri/ /en/index.html;
    }
    
    location /ru/ {
        try_files $uri $uri/ /ru/index.html;
    }
    
    location /de/ {
        try_files $uri $uri/ /de/index.html;
    }
}

Подводные камни и решения

Проблема: Размер проекта растёт с каждым языком

Решение: Используй lazy loading для языковых модулей или рассмотри ngx-translate для рантайм-переключения

Проблема: Сложность CI/CD для множественных сборок

Решение: Автоматизируй через Docker и GitHub Actions

# Dockerfile
FROM node:16-alpine AS builder
WORKDIR /app
COPY package*.json ./
RUN npm ci
COPY . .
RUN npm run build:i18n

FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
COPY nginx.conf /etc/nginx/nginx.conf

Интеграция с системами переводов

Для больших проектов стоит интегрироваться с профессиональными системами переводов:

  • Crowdin — поддерживает XLIFF из коробки
  • Lokalise — хорошая интеграция с Angular CLI
  • Transifex — мощные API для автоматизации

Пример интеграции с Crowdin CLI:

npm install -g @crowdin/cli

# crowdin.yml
project_id: "your-project-id"
api_token: "your-api-token"
base_path: "."
files:
  - source: "src/locale/messages.xlf"
    translation: "src/locale/messages.%locale%.xlf"

Нестандартные способы использования

Вот несколько хаков, которые могут пригодиться:

Условная загрузка модулей по локали

// locale.service.ts
@Injectable()
export class LocaleService {
  loadLocaleData(locale: string) {
    return import(`@angular/common/locales/${locale}`)
      .then(module => {
        registerLocaleData(module.default);
      });
  }
}

Кастомные пайпы для специфичных форматов

@Pipe({name: 'phoneNumber'})
export class PhoneNumberPipe implements PipeTransform {
  transform(value: string, locale: string): string {
    switch(locale) {
      case 'ru':
        return value.replace(/(\d{1})(\d{3})(\d{3})(\d{2})(\d{2})/, '+$1 ($2) $3-$4-$5');
      case 'de':
        return value.replace(/(\d{2})(\d{3})(\d{3})(\d{4})/, '+$1 $2 $3 $4');
      default:
        return value;
    }
  }
}

Мониторинг и аналитика

Не забывай отслеживать, какие языки используются:

// analytics.service.ts
@Injectable()
export class AnalyticsService {
  trackLanguageUsage() {
    const locale = document.documentElement.lang;
    
    // Отправляем в Google Analytics
    gtag('event', 'language_selected', {
      'language': locale,
      'user_agent': navigator.userAgent
    });
  }
}

Тестирование многоязычных приложений

Автоматизируй тестирование всех языковых версий:

// e2e/i18n.spec.ts
describe('i18n App', () => {
  const languages = ['en', 'ru', 'de'];
  
  languages.forEach(lang => {
    it(`should display welcome message in ${lang}`, () => {
      cy.visit(`/${lang}`);
      cy.get('[data-cy=welcome]').should('be.visible');
    });
  });
});

Развёртывание на VPS

Для размещения многоязычного приложения тебе понадобится надёжный VPS или выделенный сервер. Особенно это важно, если планируешь автоматические сборки и развёртывания через CI/CD.

Заключение и рекомендации

Angular i18n — мощный инструмент для создания многоязычных приложений, но он требует продуманной архитектуры. Используй его, если:

  • У тебя статичный контент, который не меняется часто
  • Производительность критична
  • Готов настроить сложную систему сборки

Для быстрого прототипирования или частых изменений переводов лучше взять ngx-translate или Transloco.

Главное — не забывай про SEO: каждая языковая версия должна быть доступна по уникальному URL, иметь правильные мета-теги и hreflang атрибуты. И обязательно тестируй на реальных пользователях — автоматические переводы могут быть неточными.

Удачи в создании международных приложений!


В этой статье собрана информация и материалы из различных интернет-источников. Мы признаем и ценим работу всех оригинальных авторов, издателей и веб-сайтов. Несмотря на то, что были приложены все усилия для надлежащего указания исходного материала, любая непреднамеренная оплошность или упущение не являются нарушением авторских прав. Все упомянутые товарные знаки, логотипы и изображения являются собственностью соответствующих владельцев. Если вы считаете, что какой-либо контент, использованный в этой статье, нарушает ваши авторские права, немедленно свяжитесь с нами для рассмотрения и принятия оперативных мер.

Данная статья предназначена исключительно для ознакомительных и образовательных целей и не ущемляет права правообладателей. Если какой-либо материал, защищенный авторским правом, был использован без должного упоминания или с нарушением законов об авторском праве, это непреднамеренно, и мы исправим это незамедлительно после уведомления. Обратите внимание, что переиздание, распространение или воспроизведение части или всего содержимого в любой форме запрещено без письменного разрешения автора и владельца веб-сайта. Для получения разрешений или дополнительных запросов, пожалуйста, свяжитесь с нами.

Leave a reply

Your email address will not be published. Required fields are marked