Skip to content

console: the language menu is a hardcoded list of 10 codes — it never asks the app which locales it actually ships #5418

Description

@yinlianghui

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.

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions