Skip to content

fix(i18n): translate Setup System Settings menu labels and pages#1670

Merged
os-zhuang merged 4 commits into
mainfrom
claude/laughing-rosalind-abe821
Jun 9, 2026
Merged

fix(i18n): translate Setup System Settings menu labels and pages#1670
os-zhuang merged 4 commits into
mainfrom
claude/laughing-rosalind-abe821

Conversation

@baozhoutao

@baozhoutao baozhoutao commented Jun 9, 2026

Copy link
Copy Markdown
Contributor

Problem

i18n Finding — System Settings has untranslated menu labels/pages.

The Setup app ("System Settings") rendered most of its left-nav menu in
English even for zh-CN / ja-JP / es-ES users. Investigation found
two independent causes — a missing-data gap and a structural bug at
the REST translation boundary.

1. Root cause — getMetaItem envelope was never unwrapped before translation

GET /meta/app/setup for the single-item app route bypasses the HTTP
cache by design
(per-user RBAC filtering via filterAppForUser), so it
received the raw getMetaItem envelope { type, name, item, lock, … }
and passed the whole envelope to translateMetadataDocument. But the
translatable document — and its navigation tree — lives nested at
.item. The resolver found no navigation on the envelope's top level,
so it walked nothing and left every menu label in English; only the
envelope's own top-level label got translated, which consumers reading
.item never see.

The cached read path passes the already-unwrapped document, so it was
never affected — which is exactly why the bug only showed on the
cache-bypassing app route.

A parallel bug: list endpoints ({ items: [...] } shape) were dropped
untranslated by a bare Array.isArray(items) guard.

2. Missing translation keys

Several Setup nav entries had no bundle key in any locale, so they
fell back to English regardless of the above:

  • Configuration settings pages: nav_settings_auth/storage/ai/knowledge/feature_flags
  • group_integrations (the Setup app's own empty integrations anchor)
  • nav_notification_{preferences,subscriptions,templates} (contributed to
    group_configuration by @objectstack/service-messaging, which ships
    no translation bundle)
  • Per-manifest settings page content (auth/ai/knowledge) missing
    for some locales.

Changes

packages/rest/src/rest-server.ts — the structural fix

  • Add isMetaEnvelope() and unwrap the inner document before calling
    translateMetadataDocument in both translateMetaItem and
    translateMetaItems.
  • translateMetaItems now also handles the { items: [...] } list-envelope
    shape (previously dropped untranslated).

packages/rest/src/rest.test.ts — 4 regression tests covering envelope
unwrap, the bare-document path, and both list shapes ({items} + raw array).

packages/platform-objects/src/apps/translations/{en,zh-CN,ja-JP,es-ES}.ts
— Setup nav menu labels: nav_settings_auth/storage/ai/knowledge/feature_flags,
group_integrations, and nav_notification_{preferences,subscriptions,templates}.

packages/services/service-settings/src/translations/{zh-CN,ja-JP,es-ES}.ts
— settings page content for auth (+ ai/knowledge for ja-JP).

en stays the source of truth; all keys mirror the manifest/nav-node names
so the locale → fallback → literal resolver chain stays intact.

Verification

End-to-end against a running dev server (zh-CN):

  • APIGET /api/v1/meta/app/setup with Accept-Language: zh-CN:
    item.label系统设置, and 0 remaining English nav labels across
    the whole tree (every group + leaf, including the type:'url' settings
    items and the notification entries).
  • UI — the Console's System Settings sidebar renders fully localized:
    全部设置 · 品牌 · 认证 · 邮件 · 文件存储 · AI 与 Embedder · 知识库 ·
    功能开关 · 通知偏好 · 通知订阅 · 通知模板.
  • Tests@objectstack/rest 100/100 pass (96 existing + 4 new
    regression cases). @objectstack/platform-objects builds clean.

Scope / follow-ups

  • Covers the four shipped locales (en, zh-CN, ja-JP, es-ES).
  • The notification nav labels currently live in the central
    SetupAppTranslations (alongside nav_notifications) since they merge
    into the Setup app by stable id. If @objectstack/service-messaging
    later grows its own translation bundle, they could move there.

The Setup app's Configuration menu gained Authentication, File Storage,
AI & Embedder, and Knowledge entries, but their nav labels were never
added to the translation bundles, and several settings pages had no
localized content. Untranslated locales fell back to the raw English
literal (or key).

Setup nav menu labels (platform-objects):
- Add nav_settings_storage / nav_settings_ai / nav_settings_knowledge
  to en, zh-CN, ja-JP, es-ES.
- Add the missing nav_settings_auth label to zh-CN, ja-JP, es-ES.

Settings page content (service-settings):
- Add the auth page to zh-CN, ja-JP, es-ES.
- Add the ai and knowledge pages to ja-JP.

en remains the source of truth; keys mirror the manifest field names.
@vercel

vercel Bot commented Jun 9, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
spec Ready Ready Preview, Comment Jun 9, 2026 7:47am

Request Review

The single-item app route bypasses the HTTP cache (for per-user RBAC
filtering), so it received the raw `getMetaItem` envelope
`{ type, name, item, ... }` and passed it straight to
`translateMetadataDocument`. Because the translatable document — and
its `navigation` tree — lives nested at `.item`, the resolver found no
`navigation` to walk and left every Setup menu label in English; only
the envelope's own top-level label got translated, which consumers
reading `.item` never see.

Add `isMetaEnvelope` and unwrap the inner document before translating in
both `translateMetaItem` and `translateMetaItems`. Also handle the
`{ items: [...] }` list-envelope shape in `translateMetaItems`, which the
bare `Array.isArray` guard previously dropped untranslated.
…ons)

The Setup app left four nav labels in English because no bundle key
existed for them across any locale:
  - group_integrations (the empty integrations anchor owned by the
    Setup app itself; only the singular group_integration for Studio
    was translated)
  - nav_notification_{preferences,subscriptions,templates} (contributed
    to group_configuration by @objectstack/service-messaging, which
    ships no translation bundle)

These merge into the Setup app by stable node id, so their labels
belong in the central SetupAppTranslations alongside nav_notifications.
Add all four to en, zh-CN, ja-JP and es-ES.
Cover the regression directly: a getMetaItem envelope must have its
nested .item translated (not the envelope top level), the bare
already-unwrapped document path must still work, and both list shapes
({items:[...]} and a raw array) must localize their elements.
@baozhoutao

Copy link
Copy Markdown
Contributor Author

Scope note: while verifying this PR I found that the System Settings pages (/apps/setup/system/settings, .../branding, .../auth, …) render blank in the console. That is a separate issue — the console SPA (objectui) has no system/settings route or manifest-driven settings UI; the /api/settings backend works and the menu labels (this PR) translate correctly. Tracked separately as objectstack-ai/objectui#1609 so this i18n PR stays focused.

@os-zhuang os-zhuang merged commit e7f8e56 into main Jun 9, 2026
12 checks passed
@os-zhuang os-zhuang deleted the claude/laughing-rosalind-abe821 branch June 9, 2026 15:04
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants