Preact как легковесная альтернатива React предоставляет гибкие возможности для интеграции интернационализации (i18n). В отличие от крупных фреймворков, Preact не имеет встроенной системы локализации, что делает необходимым использование сторонних библиотек или написание собственной инфраструктуры для работы с переводами.
Ключевая цель интернационализации — обеспечить динамическое отображение текста, чисел, дат и других локализованных элементов в зависимости от выбранного языка пользователя.
Типичная структура проекта с поддержкой нескольких языков включает:
// 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"
};
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;
}
import { h } from 'preact';
import { t } from './i18n';
function Greeting() {
return <p>{t('greeting')}</p>;
}
Несмотря на минимализм Preact, многие библиотеки, разработанные для
React, совместимы с Preact через preact/compat. Наиболее
популярные решения:
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>;
}
<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 обеспечивает корректное отображение денежных
единиц, процентов и дат без дополнительных зависимостей.
При использовании 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, например:
Создаётся скрипт, который обновляет файлы локалей автоматически, что значительно ускоряет работу с большим количеством языков и ключей.
Эта структура и методы позволяют создавать масштабируемые Preact-приложения с поддержкой многоязычности, обеспечивая корректное отображение текстов, дат и чисел для любых региональных настроек.