Repository navigation
Bring autobot-slm-frontend to all 11 locales #14781
Copy link
Copy link
Closed
Labels
area: frontend-unificationWave 4 · cluster B — Frontend unification & design systemWave 4 · cluster B — Frontend unification & design systemfrontendi18nInternationalization & multi-language supportInternationalization & multi-language supportpriority: hightechnical-debt
Milestone
Description
Part of #14774.
Problem
autobot-slm-frontend ships a single locale. src/i18n/index.ts imports only @/locales/en.json and hardcodes locale: 'en'; src/locales/ contains just en.json.
autobot-frontend ships 11 locales: ar, de, en, es, fa, fr, he, lv, pl, pt, ur — four of them RTL.
This is a standing violation of the project's i18n rule independent of any component work, and it blocks the unification umbrella: every shared component with user-facing copy either cannot ship to the SLM control plane, or silently ships English there.
Approach
- Extend
autobot-slm-frontend/src/locales/to all 11 locales. - Replace the hardcoded
locale: 'en'insrc/i18n/index.tswith the same detection/persistence the main GUI uses. - Add a language switcher to the SLM shell (the main GUI's
components/layout/LanguageSwitcher.vueis a candidate for promotion into the shared kit). - Add RTL layout support and verify against
ar/fa/he/ur. - Wire the SLM GUI into the existing locale-completeness checks —
autobot-frontendrunscheck:i18n(scripts/check-i18n-keys.mjs) andcheck:locales(scripts/check-locale-completeness.py); the SLM GUI runs neither.
Risks / constraints
- Translation content for 10 new locales is the bulk of the effort; scope the mechanism and the key extraction first so the work is not blocked on copy.
- RTL is a layout change, not only a text change — the SLM GUI is utility-first, so directional utilities (
ml-,pl-,left-) need auditing for logical-property equivalents. - Do not add the locale files without wiring the completeness check, or they will drift immediately.
Acceptance criteria
-
autobot-slm-frontend/src/locales/contains all 11 locale files -
src/i18n/index.tsno longer hardcodes a locale - Language switcher present in the SLM shell
- RTL verified against at least one RTL locale
-
check:i18nandcheck:localesrun againstautobot-slm-frontendin CI - A guard test fails if a key exists in one locale but not the others
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
area: frontend-unificationWave 4 · cluster B — Frontend unification & design systemWave 4 · cluster B — Frontend unification & design systemfrontendi18nInternationalization & multi-language supportInternationalization & multi-language supportpriority: hightechnical-debt
Activity
mrveiss commentedon Aug 28, 2026
Confirmed 2026-08-28 — the plumbing is done, only the locale files are missing
Re-measured against the current tree, and the shape of this issue is better than the title
suggests:
.vuefiles using translation callssrc/locales/en.jsonsrc/i18n/index.tsSo 98% of SLM components already call
t(). This is not a wiring task — the components aretranslation-ready and the work is producing the 10 missing locale files, matching
autobot-frontend/src/i18n/locales/which carries all 11 (ar,de,en,es,fa,fr,he,lv,pl,pt,ur).Two things worth knowing before the locales land:
ar,fa,he,ur), andautobot-slm-frontendhas zerofiles referencing
rtltoday. The main GUI has the same defect at scale — 211 physicaldirection properties against 3 logical ones — now filed as style(frontend): 4 RTL locales ship against 211 physical direction properties and 3 logical ones — Arabic, Farsi, Hebrew and Urdu render mirrored in text but not in layout #15216. Adding RTL locales here
without logical properties ships the same broken layout a second time. Worth sequencing style(frontend): 4 RTL locales ship against 211 physical direction properties and 3 logical ones — Arabic, Farsi, Hebrew and Urdu render mirrored in text but not in layout #15216's
approach into this work, or at minimum converting SLM's direction properties first, while its
surface is small (109 components versus 451).
t()should be checked for hardcoded strings before the localefiles are generated, so they are not missed in the extraction.
mrveiss commentedon Aug 28, 2026
Blocked by #15216 — adding the locale files first ships the RTL defect a second time
Recording this here rather than in a tracker note, because this is where someone will pick the work up, and from the issue title it reads like an easy win: ten JSON files, 107 of 109 components already calling
t().It is not wiring, and that is exactly the problem. The wiring is done. What remains is adding locales — and four of the eleven are RTL (Arabic, Farsi, Hebrew, Urdu). The SLM frontend has zero
rtlreferences today, and #15216 measured the main GUI at 211 physical direction properties against 3 logical ones.So the sequence matters in one direction only:
left/right,margin-left,padding-right,text-align: left) to logical ones (inline-start/inline-end) so layout can mirror.Land them the other way round and four locales ship with text that mirrors and layout that does not — the defect #15216 exists to fix, reproduced in a second GUI, at 109 components against the main GUI's 451.
One framing correction worth carrying: SLM's smaller surface makes it the cheaper place to fix direction properties, which is true but is not the ordering argument. The ordering argument is that neither GUI should gain RTL locales before its layout can mirror. SLM simply has the advantage of not having shipped them yet — the main GUI does not, which is why #15216 is remediation there and prevention here.
Both issues stay in their own clusters — this is a dependency, not a shared workstream, and merging them would misplace one of them.
Refs #15216, #11515.
feat(slm): Data hygiene page -- orphan storage propose, orphan repair…
fix(slm-frontend): name the locale type parameter instead of inheriti…
fix(ci): give the i18n guards an interpreter, and audit the locale ba…
fix(slm-frontend): a PEM specimen is not a translatable string (#14781)
docs(slm-frontend): state the three boundaries the guards do not cover (
fix(ci): the condition is "only pytest is installed", not "fastapi is…
6 remaining items
guard(reach): migrate the two SLM frontend floors to declare(), re-me…
docs(locales): say what flatten does, not what its name already says (#…
fix(prepush): point the glob record at where the record now lives (#1…
fix(guards): the bare-pytest guard could not see the failure it docum…
fix(guards): an i18n guard that could not read four of its own locales (
fix(i18n): apply the reviewer's lv/pl/ur corrections, refuse the two …
fix(i18n,guards): correct the translations at their source, and lower…
feat(slm-frontend): all 11 locales, a way to reach them, and a gate t…
mrveiss commentedon Sep 28, 2026
Classification (for work assignment — not a fix proposal)
slm-frontend: i18n locales, the language switcher, RTL, and locale CI checks for the SLM GUI.autobot-slm-frontend/src/locales/(verified on main; now holds all 11 locale files)autobot-slm-frontend/src/i18n/index.ts(verified on main; its header says "all 11 locales, no hardcoded language (Bring autobot-slm-frontend to all 11 locales #14781)")autobot-slm-frontend/src/components/common/LanguageSwitcher.vue(verified on main)autobot-slm-frontend/src/i18n/__tests__/locales.spec.ts(verified on main)autobot-slm-frontend/package.json(verified on main; thecheck:i18nandcheck:localesscripts).github/workflows/slm-frontend-check.yml(verified on main; runs both checks)9239fbc59("all 11 locales, a way to reach them, and a gate that keeps them (Bring autobot-slm-frontend to all 11 locales #14781, fix(slm-frontend): the log viewer's "No logs available" is a bare literal, and no i18n gate covers this app #15665)") is on main. Not verified: whether each criterion is met, notably "RTL verified". That needs a per-criterion check before closure.Generated by Claude Code
mrveiss commentedon Sep 28, 2026
Chunk triage —
v0.9.2 node plane and deploy. Read-only atorigin/main7adaca8c29; nothing labelled or moved.The premise has moved: this issue's opening claim is no longer true, and most of it looks delivered.
The body says "
autobot-slm-frontendships a single locale … imports only@/locales/en.jsonand hardcodeslocale: 'en'". On currentmain:autobot-slm-frontend/src/locales/holds 11:ar de en es fa fr he lv pl pt ursrc/i18n/index.tsno longer hardcodes a locale:8records that the module "used to importen.jsonalone";:99setsfallbackLocale: 'en', which is a fallback, not a hardcoded localesrc/components/common/LanguageSwitcher.vue, referenced fromSidebar.vuecheck:i18n/check:localesin CI.github/workflows/slm-frontend-check.yml:123and:129slm-frontend-check.yml:129describes two checks, the second being the parity one; worth one read before ticking9239fbc595— "feat(slm-frontend): all 11 locales, a way to reach them, and a ga…", which is this issue's subject verbatim — plus PR#17395 and PR#16239 merged.priority: highin a chunk ordered on criticality it would displace real work.mrveiss commentedon Sep 28, 2026
Closure pass — 5 of 6 criteria met from merged code. The sixth is one sentence of ambiguity away from closing, and I am not resolving it by guessing. Not closed.
Evidence at
origin/main7adaca8c29; landed via9239fbc595"feat(slm-frontend): all 11 locales, a way to reach them, and a ga…" (PR#17395, PR#16239).The issue's opening premise is now false, which is worth saying before the criteria: it reads "
autobot-slm-frontendships a single locale … imports only@/locales/en.jsonand hardcodeslocale: 'en'." Neither half holds.AC1 — all 11 locale files — MET.
autobot-slm-frontend/src/locales/holds exactly the main GUI's set:ar de en es fa fr he lv pl pt ur.AC2 — no hardcoded locale — MET, and by derivation rather than a list.
src/i18n/index.ts::29-30— "Every locale on disk — derived, never a hand-kept list (refactor(i18n): derive SUPPORTED_LOCALES from locale file glob instead of hardcoding #1675)", viaimport.meta.glob('../locales/*.json', { eager: true }). A twelfth locale needs no edit here.:53detectBrowserLocale()matchesnavigator.languagesagainst what is on disk, exact match first;:68prefers a stored preference when it is a locale we actually have, else detection.:22-23— direction comes from the locale's own_meta.dir"so an app can never disagree with its own locale file about" it (refactor(i18n): derive RTL_LOCALES from locale file metadata instead of hardcoding #1812).AC3 — a language switcher in the SLM shell — MET.
src/components/common/Sidebar.vue:16imports it and:358renders<LanguageSwitcher />. Rendered in the shell, not merely present in the tree.AC5 —
check:i18nandcheck:localesrun against this app in CI — MET, with a third step beyond the criterion..github/workflows/slm-frontend-check.yml::121-123i18n keys,:132-134locale parity, and:136-139lift_locale_translations.py --check— "the generator's own--check, which is why the generation is a script in the repo rather than a one-off someone ran."AC6 — a guard fails when a key exists in one locale and not the others — MET.
check:localesis that guard, and the comment at:125-131states the failure mode it exists for: "vue-i18n then falls back silently, so the gap is invisible until someone reads that language." That is the right reason for the guard rather than a tidiness rule.AC4 — "RTL verified against at least one RTL locale" — half verified in the tree, and the half that decides it is ambiguous
What is verified, in code and by test:
_meta: {"dir": "rtl"}(ar,fa,he,ur) andencarries"ltr";src/i18n/__tests__/locales.spec.ts:38-40assertsgetLocaleDir(locale)is'rtl'for the RTL set, and:47that "an unknown locale [is treated] as left-to-right rather than throwing".What is not: that a rendered SLM page in Arabic lays out correctly. Direction resolving to
rtland a layout being right in RTL are different claims, and only the first is in the tree.So the criterion turns on what "verified" means, and that is a one-line decision rather than work:
locales.spec.ts:38-47, and this issue closes today;v0.9-host, and the other five criteria are done.I am not picking, because the two answers put the issue in different milestones. Everything else is delivered and ticked.
mrveiss commentedon Sep 28, 2026
AC4 settled on the criterion's own wording. All six met — closing.
The criterion reads "RTL verified against at least one RTL locale." Against that wording, it is met on
maintoday:src/i18n/__tests__/locales.spec.ts:38-40—getLocaleDir(locale)asserts'rtl'for the RTL set (ar,fa,he,ur);:47— an unknown locale resolves left-to-right rather than throwing, so the default is pinned and not incidental;src/i18n/index.ts:22-23— direction is derived from the locale file's own_meta.dir, "so an app can never disagree with its own locale file about" it (refactor(i18n): derive RTL_LOCALES from locale file metadata instead of hardcoding #1812);ar/fa/he/ur→{"dir": "rtl"},en→{"dir": "ltr"}.That is verification against an RTL locale, in a test, in the tree.
Note, deliberately not a criterion: what was not shown
A rendered SLM page in an RTL locale has not been observed. The direction mechanism is tested; the layout is not. Resolving
dirtortland a page laying out correctly in RTL are different claims, and only the first is in the repository.Recorded this way on purpose. Reading the criterion to mean a rendered page is stricter than the words it uses, and a five-of-six issue should not sit open — or move to a host milestone — on an interpretation. If the rendered check is wanted, it is one line to file, and this note says exactly what was and was not demonstrated so nobody re-derives it.
The six, for the record
src/locales/=ar de en es fa fr he lv pl pt uri18n/index.ts:29-30derives the set fromimport.meta.glob, "never a hand-kept list (#1675)";:53browser detection;:68stored preference only when the locale existsSidebar.vue:16imports,:358renders<LanguageSwitcher />locales.spec.ts:38-47(above)check:i18n/check:localesin CIslm-frontend-check.yml:121-123,:132-134, plus:136-139lift_locale_translations.py --checkcheck:locales, with the reason at:125-131— "vue-i18n then falls back silently, so the gap is invisible until someone reads that language"Landed via
9239fbc595(PR#17395, PR#16239). The issue's opening premise — "ships a single locale … hardcodeslocale: 'en'" — has not been true for some time; the interpretation question is what kept it open, not the work.Closing.