SkateJS — это современная библиотека для создания веб-компонентов, построенная на стандартных возможностях Custom Elements и Shadow DOM. Организация мультиязычности в компонентах SkateJS требует системного подхода, который объединяет реактивность, управление состоянием и динамическое обновление текста на основе выбранного языка.
В SkateJS свойства компонентов (props) играют ключевую
роль в мультиязычной архитектуре. Для реализации мультиязычности часто
создается свойство locale, которое хранит текущий язык
интерфейса. Например:
import { component, h, prop } from 'skatejs';
class MyComponent extends HTMLElement {
static props = {
locale: prop.string({ attribute: true, default: 'en' })
};
render() {
const translations = {
en: { greeting: 'Hello' },
ru: { greeting: 'Привет' },
es: { greeting: 'Hola' }
};
const t = translations[this.locale] || translations['en'];
return <div>{t.greeting}, world!</div>;
}
}
customElements.define('my-component', MyComponent);
Ключевой момент: любое изменение свойства
locale автоматически инициирует повторный рендер
компонента, благодаря реактивной системе SkateJS.
Для больших проектов удобнее хранить переводы отдельно в JSON или JS-файлах. Это позволяет динамически подгружать языковые пакеты и уменьшает размер исходного кода компонента.
Пример структуры переводов:
// locales/en.js
export default {
greeting: 'Hello',
farewell: 'Goodbye'
};
// locales/ru.js
export default {
greeting: 'Привет',
farewell: 'До свидания'
};
В компоненте это подключается через динамический импорт:
async updateLocale(lang) {
const translations = await import(`./locales/${lang}.js`);
this.translations = translations.default;
this.update(); // вручную инициируем повторный рендер
}
Особенность SkateJS: this.update()
можно использовать для ручного обновления, если изменение данных
происходит вне реактивных свойств.
Чтобы компонент автоматически менял язык при изменении свойства
locale, можно использовать хук updated:
updated(prevProps) {
if (prevProps.locale !== this.locale) {
this.loadTranslations(this.locale);
}
}
async loadTranslations(lang) {
const translations = await import(`./locales/${lang}.js`);
this.translations = translations.default;
}
Здесь updated позволяет отслеживать изменения и
подгружать нужные переводы без перезагрузки страницы.
Мультиязычность включает не только тексты, но и форматирование дат,
чисел и валют. В SkateJS это можно интегрировать через стандартный API
Intl:
const date = new Date();
const formattedDate = new Intl.DateTimeFormat(this.locale, {
year: 'numeric',
month: 'long',
day: 'numeric'
}).format(date);
return <div>{formattedDate}</div>;
Преимущество: поддержка локализации без сторонних библиотек, полная совместимость с любым языком, поддерживаемым браузером.
Помимо текста, важно локализовать пользовательские события и атрибуты компонента. Например, если компонент генерирует уведомления:
this.dispatchEvent(new CustomEvent('message', {
detail: { text: this.translations.farewell }
}));
Это гарантирует, что внешний код, подписанный на события компонента, всегда получает корректный текст на текущем языке.
Для языков с правосторонним письмом (rtl) необходимо
менять CSS компонента динамически:
static get observedAttributes() {
return ['locale'];
}
attributeChangedCallback(name, oldValue, newValue) {
if (name === 'locale') {
this.style.direction = newValue === 'ar' ? 'rtl' : 'ltr';
}
}
Такой подход совместим с Shadow DOM, поскольку стили применяются внутри компонента без утечки на другие элементы страницы.
SkateJS можно легко интегрировать с i18n-библиотеками, такими как
i18next, для управления сложными проектами. Основная идея
сохраняется: локаль хранится в свойстве, а перевод берется из
централизованного менеджера.
import i18next from 'i18next';
class MyComponent extends HTMLElement {
static props = { locale: prop.string({ attribute: true }) };
updated(prevProps) {
if (prevProps.locale !== this.locale) {
i18next.changeLanguage(this.locale);
this.update();
}
}
render() {
return <div>{i18next.t('greeting')}</div>;
}
}
Реализация мультиязычности в SkateJS строится на комбинации реактивных свойств, динамических переводов, корректного форматирования данных и учета специфики различных языков (LTR/RTL). Такой подход обеспечивает модульность, легкость масштабирования и полную совместимость с современными веб-стандартами.