Конвенция, применённая в gnexus-creds и hard-panel: без vue-i18n, один общий модуль, три языка.
profile.locale).locale) и переживает logout и обновление профиля через вебхуки (upsert профиля не трогает locale).auto нет.src/i18n/index.js: locale = ref("en"), normalizeTag («en-US» → «en»), t(slug, params) с интерполяцией {param} и fallback на английский, setLocale + watch(locale) → <html lang> и <title>.src/i18n/messages/{en,uk,ru}.js: плоские ключи по областям (dash.*, server.*, storage.*…), одинаковые slugs во всех словарях.params.n; строки с несколькими счётчиками собираются вложенными t(), а не плюральным слагом.GET /me возвращает выбранный и эффективный язык (locale + locale_effective = override → account → en); PATCH /me меняет override (по cookie-сессии — см. auth.md).t() застывают — таблицы колонок, опции селектов и списки навигации обязательно computed.panel/frontend/src/i18n/index.js и gnexus-creds/frontend/src/i18n/index.js