Stimulus — это легковесный JavaScript-фреймворк, ориентированный на улучшение взаимодействия с DOM без необходимости сложной структуры компонентов. Одной из часто встречающихся задач является реализация поддержки множественных языков (i18n) на клиентской стороне. Stimulus обеспечивает удобный способ организации кода для динамического изменения текста и поведения интерфейса в зависимости от выбранного языка.
Контроллеры Stimulus позволяют инкапсулировать логику управления DOM-элементами. Для поддержки нескольких языков создается отдельный контроллер, отвечающий за локализацию.
// controllers/locale_controller.js
import { Controller } from "@hotwired/stimulus"
export default class extends Controller {
static values = {
locale: String,
translations: Object
}
connect() {
this.updateText()
}
changeLocale(event) {
this.localeValue = event.target.value
this.updateText()
}
updateText() {
const texts = this.translationsValue[this.localeValue] || {}
Object.entries(texts).forEach(([key, value]) => {
const element = this.element.querySelector(`[data-locale-key="${key}"]`)
if (element) element.textContent = value
})
}
}
Ключевые моменты:
static values позволяет передавать контроллеру данные
из HTML.updateText динамически обновляет содержимое
элементов на основе выбранного языка.data-locale-key используется для привязки
конкретных элементов к соответствующим переводам.Для удобства переводы обычно организуются в объекте с ключами языков:
{
en: {
greeting: "Hello",
farewell: "Goodbye"
},
ru: {
greeting: "Привет",
farewell: "До свидания"
},
es: {
greeting: "Hola",
farewell: "Adiós"
}
}
Такой формат позволяет легко добавлять новые языки и поддерживать существующие переводы централизованно.
<div data-controller="locale"
data-locale-locale-value="en"
data-locale-translations-value='{
"en": {"greeting":"Hello","farewell":"Goodbye"},
"ru": {"greeting":"Привет","farewell":"До свидания"},
"es": {"greeting":"Hola","farewell":"Adiós"}
}'>
<p data-locale-key="greeting"></p>
<p data-locale-key="farewell"></p>
<select data-action="change->locale#changeLocale">
<option value="en">English</option>
<option value="ru">Русский</option>
<option value="es">Español</option>
</select>
</div>
Особенности реализации:
data-controller="locale" подключает контроллер к
DOM-элементу.<select> с
data-action="change->locale#changeLocale" автоматически
вызывает метод контроллера при смене языка.data-locale-translations-value. Для больших наборов
переводов рекомендуется загружать их асинхронно через fetch.В больших проектах загрузка всех языков сразу может быть неоптимальна. Stimulus позволяет интегрировать асинхронную подгрузку:
async changeLocale(event) {
const newLocale = event.target.value
const response = await fetch(`/locales/${newLocale}.json`)
this.translationsValue = await response.json()
this.localeValue = newLocale
this.updateText()
}
Преимущества такого подхода:
Stimulus использует минималистичный реактивный подход. Изменение
значения localeValue автоматически отражается на всех
связанных элементах через вызов метода updateText. Это
исключает необходимость ручного управления DOM при каждом изменении
языка и делает код более чистым и поддерживаемым.
Для проектов с серверной генерацией страниц удобно комбинировать Stimulus с серверными библиотеками i18n:
Для масштабных приложений рекомендуется:
Stimulus предоставляет гибкий и лаконичный способ реализации многоязычного интерфейса. Контроллеры с реактивными значениями, структурированные данные переводов и возможности асинхронной загрузки позволяют создавать масштабируемые и удобные для поддержки решения.