Библиотеки для интернационализации

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

Ключевая цель интернационализации — обеспечить динамическое отображение текста, чисел, дат и других локализованных элементов в зависимости от выбранного языка пользователя.


Структура локализации

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

  1. Файлы переводов Каждый язык представлен отдельным файлом или модулем, содержащим ключи и соответствующие значения:
// locales/en.js
export default {
  greeting: "Hello",
  farewell: "Goodbye",
  date_format: "MM/DD/YYYY"
};

// locales/ru.js
export default {
  greeting: "Привет",
  farewell: "До свидания",
  date_format: "DD.MM.YYYY"
};
  1. Менеджер локализации Модуль, который хранит текущий язык и предоставляет функции для получения перевода по ключу:
import en from './locales/en';
import ru from './locales/ru';

const locales = { en, ru };
let currentLang = 'en';

export function setLanguage(lang) {
  if (locales[lang]) currentLang = lang;
}

export function t(key) {
  return locales[currentLang][key] || key;
}
  1. Использование в компонентах Preact
import { h } from 'preact';
import { t } from './i18n';

function Greeting() {
  return <p>{t('greeting')}</p>;
}

Сторонние библиотеки для Preact

Несмотря на минимализм Preact, многие библиотеки, разработанные для React, совместимы с Preact через preact/compat. Наиболее популярные решения:

  1. react-i18next Позволяет управлять переводами, поддерживает ленивую загрузку языков и работу с форматированием дат и чисел.
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';

i18n
  .use(initReactI18next)
  .init({
    resources: {
      en: { translation: { greeting: "Hello" } },
      ru: { translation: { greeting: "Привет" } }
    },
    lng: "en",
    fallbackLng: "en",
    interpolation: { escapeValue: false }
  });

import { useTranslation } from 'react-i18next';

function Greeting() {
  const { t } = useTranslation();
  return <p>{t('greeting')}</p>;
}
  1. preact-i18n Легкая библиотека, созданная специально для Preact. Она использует контекст для передачи текущего языка и компонент <Text> для отображения перевода:
import { I18n, Text } from 'preact-i18n';

const messages = {
  en: { greeting: "Hello" },
  ru: { greeting: "Привет" }
};

function App({ lang }) {
  return (
    <I18n definition={messages[lang]}>
      <Text id="greeting" />
    </I18n>
  );
}

Динамическая смена языка

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

import { h } from 'preact';
import { useState } from 'preact/hooks';
import { I18n, Text } from 'preact-i18n';
import messages from './locales';

function App() {
  const [lang, setLang] = useState('en');

  return (
    <div>
      <button onCl ick={() => setLang('en')}>English</button>
      <button onCl ick={() => setLang('ru')}>Русский</button>
      <I18n definition={messages[lang]}>
        <p><Text id="greeting" /></p>
      </I18n>
    </div>
  );
}

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


Форматирование чисел и дат

Для локализации чисел и дат используется стандарт Intl или сторонние библиотеки:

const number = 123456.78;

const formattedNumberRU = new Intl.NumberFormat('ru-RU').format(number); // 123 456,78
const formattedNumberEN = new Intl.NumberFormat('en-US').format(number); // 123,456.78

const date = new Date();
const formattedDateRU = new Intl.DateTimeFormat('ru-RU').format(date);
const formattedDateEN = new Intl.DateTimeFormat('en-US').format(date);

Intl обеспечивает корректное отображение денежных единиц, процентов и дат без дополнительных зависимостей.


Стратегии оптимизации

  • Ленивая загрузка языков: загружать только нужный язык по запросу, уменьшает размер бандла.
  • Кеширование переводов: хранение локалей в IndexedDB или localStorage для уменьшения количества сетевых запросов.
  • Разделение ключей на категории: улучшает структуру и облегчает поддержку больших проектов.

Интеграция с роутером

При использовании preact-router удобно синхронизировать язык с URL:

<Route path="/:lang/home" component={Home} />

function Home({ matches }) {
  const lang = matches.lang;
  return <I18n definition={messages[lang]}><Text id="greeting" /></I18n>;
}

Такой подход обеспечивает уникальные URL для каждого языка и улучшает SEO.


Автоматизация перевода

Для крупных проектов возможно подключение внешних сервисов перевода через API, например:

  • Google Translate API
  • Microsoft Translator API

Создаётся скрипт, который обновляет файлы локалей автоматически, что значительно ускоряет работу с большим количеством языков и ключей.


Эта структура и методы позволяют создавать масштабируемые Preact-приложения с поддержкой многоязычности, обеспечивая корректное отображение текстов, дат и чисел для любых региональных настроек.