i18n: en/uk/ru, and the interface language of the account
The client hard-coded English in every template. It now goes through t() from
src/i18n/ — a locale ref, {param} interpolation, plural dictionaries driven by
n, and flat per-area dictionaries in src/i18n/messages/ carrying the same slugs
in all three languages. vue-i18n is deliberately not pulled in: the platform
handbook rules it out, and what it would buy — plural forms, a reactive locale,
an English fallback — is about eighty lines here. A slug nobody carries falls
back to English, so a screen already translated and one still speaking
hard-coded English can coexist while the work goes area by area.

The language comes from locale_effective in GET /auth/me: the choice made in
Settings (navi_users.locale_override, a new column) over the gnexus-auth
account locale (navi_users.locale, a straight mirror the user.profile_updated
webhook keeps writing — the override sits in its own column precisely so that
mirror cannot wipe it), over en. PATCH /auth/me writes the override, and null
means "follow the account" again. With NAVI_AUTH_ENABLED=false there is no
account to follow, so the choice is kept in localStorage under navi.locale.

The picker is the first block of Settings → Account. Each language is named in
its own language, which is why those three strings are identical in all three
dictionaries. Lists of labels are computed rather than module-level constants:
one built at import would keep the language that was active then and ignore a
switch.

Checked in Chromium against the built bundle: choosing Русский rewrites
<html lang> and the document title, survives a reload, and Auto brings the
account's own language back.
1 parent 349f85b commit a521651200df890d69eb1e4779422f7dde9f9330
@Eugene Sukhodolskiy Eugene Sukhodolskiy authored 1 day ago
Showing 24 changed files
View
docs/api.md
View
docs/i18n.md 0 → 100644
View
docs/index.md
View
navi/api/routes/auth.py
View
navi/api/routes/webhooks.py
View
navi/auth/_ddl.py
View
navi/auth/deps.py
View
navi/locales.py 0 → 100644
View
tests/unit/api/test_auth_locale.py 0 → 100644
View
tests/unit/auth/test_ddl.py 0 → 100644
View
tests/unit/auth/test_deps.py
View
tests/unit/test_locales.py 0 → 100644
View
webclient/CLAUDE.md
View
webclient/src/App.vue
View
webclient/src/api/index.js
View
webclient/src/components/settings/AccountPanel.vue 0 → 100644
View
webclient/src/components/ui/LoginScreen.vue
View
webclient/src/i18n/index.js 0 → 100644
View
webclient/src/i18n/messages/en.js 0 → 100644
View
webclient/src/i18n/messages/ru.js 0 → 100644
View
webclient/src/i18n/messages/uk.js 0 → 100644
View
webclient/src/stores/auth.js
View
webclient/tests/unit/components/settings/accountPanel.test.js 0 → 100644
View
webclient/tests/unit/i18n/index.test.js 0 → 100644