Found while implementing #5406 (locale persistence). Filing only; not fixed there — out of that issue's scope.
What
packages/app-shell/src/layout/LocaleSwitcher.tsx builds its menu from a module-level LANGUAGES constant: exactly the ten codes @object-ui/i18n ships built-in packs for (en zh ja ko de fr es pt ru ar). The app's own locale set is never consulted, even though the endpoint exists and works — #5406 confirms GET /api/v1/i18n/locales lists the app's locales and that short-code resolution works.
Two consequences, in opposite directions:
- Unofferable locales. An app that ships a locale outside those ten (say
th, or a regional pt-BR) has no way to be selected from the console UI. The bundle can be complete and lint clean; the menu simply has no entry for it.
- Phantom locales. An app that ships only
en + zh still shows all ten. Picking 日本語 gives the console's own chrome in Japanese and everything app-authored in the fallback language — a half-translated UI the app author never opted into.
Why it is worth writing down now
The fix for #5406 (PR objectstack-ai/objectui#3376) validates a restored language against "the locales this provider can produce" — built-in packs plus config.resources. That bound is correct today precisely because the switcher offers exactly the built-in ten. If the menu grows to the app's real locale list, the restore validation has to grow with it in the same change, or a user-picked app locale becomes the next thing that does not survive a reload.
Suggested shape (not a decision)
Have the switcher render the intersection (or the union, with the fallback made visible) of the app's /i18n/locales response and what the renderer can resolve, with the current hardcoded list as the offline/no-backend fallback. The label metadata (中文, 日本語, …) has to come from somewhere for codes with no built-in pack — Intl.DisplayNames is the obvious candidate.
No user is currently blocked as far as I can tell: the apps in the repo use built-in codes only. Recording it so triage can grade it rather than leaving it in a PR comment.
Found while implementing #5406 (locale persistence). Filing only; not fixed there — out of that issue's scope.
What
packages/app-shell/src/layout/LocaleSwitcher.tsxbuilds its menu from a module-levelLANGUAGESconstant: exactly the ten codes@object-ui/i18nships built-in packs for (en zh ja ko de fr es pt ru ar). The app's own locale set is never consulted, even though the endpoint exists and works — #5406 confirmsGET /api/v1/i18n/localeslists the app's locales and that short-code resolution works.Two consequences, in opposite directions:
th, or a regionalpt-BR) has no way to be selected from the console UI. The bundle can be complete and lint clean; the menu simply has no entry for it.en+zhstill shows all ten. Picking 日本語 gives the console's own chrome in Japanese and everything app-authored in the fallback language — a half-translated UI the app author never opted into.Why it is worth writing down now
The fix for #5406 (PR objectstack-ai/objectui#3376) validates a restored language against "the locales this provider can produce" — built-in packs plus
config.resources. That bound is correct today precisely because the switcher offers exactly the built-in ten. If the menu grows to the app's real locale list, the restore validation has to grow with it in the same change, or a user-picked app locale becomes the next thing that does not survive a reload.Suggested shape (not a decision)
Have the switcher render the intersection (or the union, with the fallback made visible) of the app's
/i18n/localesresponse and what the renderer can resolve, with the current hardcoded list as the offline/no-backend fallback. The label metadata (中文,日本語, …) has to come from somewhere for codes with no built-in pack —Intl.DisplayNamesis the obvious candidate.No user is currently blocked as far as I can tell: the apps in the repo use built-in codes only. Recording it so triage can grade it rather than leaving it in a PR comment.