Переключение языков в приложении

Современные веб-приложения часто предназначены для пользователей из разных стран. Интернационализация (i18n) — это процесс подготовки приложения к поддержке нескольких языков и культурных форматов. В контексте интерфейсных библиотек важную роль играет корректный перевод компонентов, а также возможность динамически переключать язык без перезагрузки страницы.

В экосистеме Ant Design интернационализация реализуется через встроенную систему локалей и компонент ConfigProvider. Он позволяет определить язык интерфейса для всех компонентов библиотеки.

Переключение языков обычно включает несколько элементов:

  • набор локалей интерфейса
  • механизм хранения текущего языка
  • компонент-переключатель
  • интеграцию с системой переводов приложения

Система локалей Ant Design

Ant Design предоставляет готовые языковые пакеты. Они содержат переводы стандартных текстов компонентов: кнопок, календарей, таблиц, пагинации, модальных окон и других элементов.

Каждый пакет представляет собой объект локали.

Пример импорта локали:

import ruRU from 'antd/locale/ru_RU';
import enUS from 'antd/locale/en_US';
import zhCN from 'antd/locale/zh_CN';

Локаль передается в ConfigProvider.

import { ConfigProvider } from 'antd';

<ConfigProvider locale={ruRU}>
  <App />
</ConfigProvider>

После этого все компоненты Ant Design автоматически используют русский язык.

Примеры изменений:

Компонент Изменение
Pagination «Previous» → «Назад»
DatePicker названия месяцев
Table «No Data» → «Нет данных»
Modal «OK / Cancel» → «ОК / Отмена»

Таким образом, перевод базовых элементов не требует ручной настройки.


Архитектура переключения языков

Поддержка динамического переключения языка требует хранения текущего значения локали. Чаще всего используется один из вариантов:

  • состояние React (useState)
  • глобальное состояние (Redux, Zustand)
  • контекст (React Context)
  • локальное хранилище (localStorage)

Типичная архитектура:

App
 ├─ LanguageProvider
 │   └─ ConfigProvider (Ant Design)
 │       └─ Application Components
 └─ Language Switcher

Контекст языка управляет текущей локалью и обновляет ConfigProvider.


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

Контекст языка позволяет централизованно управлять локализацией.

Создание контекста:

import { createContext } from 'react';

export const LanguageContext = createContext({
  language: 'en',
  setLanguage: () => {}
});

Провайдер языка:

import { useState } from 'react';
import { ConfigProvider } from 'antd';
import enUS from 'antd/locale/en_US';
import ruRU from 'antd/locale/ru_RU';

const locales = {
  en: enUS,
  ru: ruRU
};

export const LanguageProvider = ({ children }) => {
  const [language, setLanguage] = useState('en');

  return (
    <LanguageContext.Provider value={{ language, setLanguage }}>
      <ConfigProvider locale={locales[language]}>
        {children}
      </ConfigProvider>
    </LanguageContext.Provider>
  );
};

Теперь при изменении language все компоненты Ant Design автоматически обновят язык.


Создание компонента переключения языка

Переключатель языка может быть реализован различными компонентами:

  • Select
  • Dropdown
  • Segmented
  • Menu

Пример с Select.

import { Sel ect } from 'antd';
import { useContext } fr om 'react';
import { LanguageContext } from './LanguageProvider';

const LanguageSwitcher = () => {
  const { language, setLanguage } = useContext(LanguageContext);

  return (
    <Sel ect
      value={language}
      onCha nge={setLanguage}
      style={{ width: 120 }}
      options={[
        { value: 'en', label: 'English' },
        { value: 'ru', label: 'Русский' }
      ]}
    />
  );
};

export default LanguageSwitcher;

При выборе нового значения происходит обновление контекста и перерисовка интерфейса.


Синхронизация с переводами приложения

Ant Design переводит только тексты собственных компонентов. Контент приложения требует отдельной системы переводов.

Популярные библиотеки:

  • react-i18next
  • react-intl
  • formatjs

Наиболее распространена библиотека react-i18next.

Пример интеграции:

import { useTranslation } fr om 'react-i18next';

const Header = () => {
  const { t } = useTranslation();

  return (
    <h1>{t('header.title')}</h1>
  );
};

Файл переводов:

{
  "header": {
    "title": "Панель управления"
  }
}

Английская версия:

{
  "header": {
    "title": "Dashboard"
  }
}

При переключении языка обновляется как Ant Design, так и пользовательские тексты.


Синхронизация локалей Ant Design и i18n

При использовании react-i18next необходимо синхронизировать язык библиотеки и Ant Design.

Пример:

import { useTranslation } from 'react-i18next';

const { i18n } = useTranslation();

useEffect(() => {
  setLanguage(i18n.language);
}, [i18n.language]);

Возможна также обратная синхронизация:

const changeLanguage = (lang) => {
  i18n.changeLanguage(lang);
  setLanguage(lang);
};

Это гарантирует единый источник истины для локализации.


Поддержка форматов дат и времени

Компоненты Ant Design, такие как DatePicker, используют библиотеку dayjs. Для корректной локализации требуется подключить соответствующий пакет.

Пример:

import dayjs from 'dayjs';
import 'dayjs/locale/ru';

dayjs.locale('ru');

После этого:

  • названия месяцев
  • формат дат
  • календарные подписи

будут соответствовать выбранному языку.

При переключении языка необходимо обновлять локаль:

useEffect(() => {
  dayjs.locale(language);
}, [language]);

Сохранение выбранного языка

Для улучшения пользовательского опыта язык интерфейса обычно сохраняется между сессиями.

Используется localStorage.

Сохранение:

localStorage.setItem('app-language', language);

Загрузка при инициализации:

const defaultLang = localStorage.getItem('app-language') || 'en';
const [language, setLanguage] = useState(defaultLang);

Обновление при изменении:

useEffect(() => {
  localStorage.setItem('app-language', language);
}, [language]);

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


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

Некоторые приложения используют язык как часть маршрута.

Примеры URL:

/en/dashboard
/ru/dashboard
/fr/dashboard

В этом случае язык определяется из параметров маршрута.

Пример с react-router.

const { lang } = useParams();
setLanguage(lang);

Преимущества такого подхода:

  • SEO-оптимизация
  • возможность делиться ссылками
  • корректная индексация поисковыми системами

Поддержка RTL-языков

Некоторые языки используют направление письма справа налево:

  • арабский
  • иврит
  • персидский

Ant Design поддерживает режим RTL через ConfigProvider.

<ConfigProvider direction="rtl">
  <App />
</ConfigProvider>

При этом:

  • элементы интерфейса отражаются
  • иконки корректно позиционируются
  • компоненты адаптируются под правостороннюю верстку

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


Lazy-загрузка локалей

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

Пример динамического импорта:

const loadLocale = async (lang) => {
  switch (lang) {
    case 'ru':
      return import('antd/locale/ru_RU');
    case 'en':
      return import('antd/locale/en_US');
    default:
      return import('antd/locale/en_US');
  }
};

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

const locale = await loadLocale(language);
setLocale(locale.default);

Это снижает первоначальный размер JavaScript-пакета.


Расширение и кастомизация локалей

В некоторых случаях требуется изменить стандартные переводы Ant Design.

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

Пример:

import ruRU from 'antd/locale/ru_RU';

const customRu = {
  ...ruRU,
  Pagination: {
    ...ruRU.Pagination,
    items_per_page: 'на странице'
  }
};

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

<ConfigProvider locale={customRu}>
  <App />
</ConfigProvider>

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


Практическая структура проекта

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

src
 ├─ i18n
 │   ├─ config.js
 │   ├─ translations
 │   │   ├─ en.json
 │   │   └─ ru.json
 │
 ├─ providers
 │   └─ LanguageProvider.jsx
 │
 ├─ components
 │   └─ LanguageSwitcher.jsx
 │
 └─ App.jsx

Такое разделение позволяет:

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

Типичные проблемы при переключении языка

1. Компоненты не обновляют язык

Причина — локаль передается не через ConfigProvider или не обновляется состояние.

2. Несинхронизированные переводы

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

3. Неверный формат даты

Не подключена локаль dayjs.

4. Язык сбрасывается при обновлении страницы

Не используется сохранение в localStorage.


Добавление нового языка

Процесс расширения системы локализации обычно включает несколько шагов:

  1. Добавление локали Ant Design
  2. Создание файлов переводов
  3. Добавление языка в переключатель
  4. Обновление конфигурации i18n

Пример добавления немецкого языка:

import deDE from 'antd/locale/de_DE';

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

const locales = {
  en: enUS,
  ru: ruRU,
  de: deDE
};

После этого интерфейс автоматически поддерживает новый язык.