Skip to content

List-view tab labels have no translation surface — 59 hardcoded English labels render untranslated in every non-en locale #661

Closed

Description

@yinlianghui

Found while scoping the zh-CN work in #645. Not covered by #494 or #645 — different root cause, and it is not fixable in this repo.

What happens

Every list view declares a tab strip, and each tab carries an inline English label:

// src/views/account.view.ts:88-94
tabs: [
  { name: 'all',        label: 'All',         view: 'all_accounts', isDefault: true, pinned: true },
  { name: 'cards',      label: 'Cards',       icon: 'gallery-thumbnails', view: 'account_gallery' },
  { name: 'map',        label: 'Map',         icon: 'map',   view: 'account_map' },
  { name: 'enterprise', label: 'Enterprise',  icon: 'crown', view: 'enterprise_accounts' },
  { name: 'mine',       label: 'My Accounts', icon: 'user',  view: 'my_accounts' },
  { name: 'renewals',   label: 'Renewals',    icon: 'refresh-cw',     view: 'renewals_due' },
  { name: 'at_risk',    label: 'At Risk',     icon: 'triangle-alert', view: 'at_risk_accounts' },
],

59 such labels across all 15 objects. They sit at the top of every list page — the first thing a user sees on entering any object — and they render in English regardless of locale.

This is more visible than the picklist gaps in #645: a Chinese user gets a fully translated sidebar, fully translated column headers, and an English tab strip between them.

Why this repo cannot fix it

There is no translation key for a tab. Verified against @objectstack/spec@17.0.0-rc.1:

  • ObjectTranslationDataSchema (dist/translation.zod-CLbo6zbE.d.ts:60-101) carries exactly label, pluralLabel, description, fields, _views, _actions, _sections. There is no _tabs.
  • @objectstack/lint — the tool that produces the i18n warnings — has handling for _views, _sections, _actions and navigation, and zero references to tabs. So these 59 labels are not merely untranslated; they are not counted as translatable, which is why they never appeared in i18n: 205 warnings hidden by --skip-i18n; broken option keys and untranslated navigation #494's 205-warning survey.

Adding a _tabs block to src/translations/*.ts would be stripped by z.core.$strip and silently do nothing.

Possible resolutions

Listing these for whoever takes it upstream — I have not verified which the console actually implements.

  1. Tab inherits its view's label. tabs[].label is already optional in the schema, and every tab here carries view: '<view_name>' pointing at a view whose label is translatable via _views. If the console falls back to the referenced view's resolved label when label is absent, this repo can fix it today by deleting all 59 inline labels — no upstream change needed. This should be checked first, since it would turn an upstream request into a one-PR app-side fix. Note the fallback would change some display text (All → 全部客户, Map → 客户地图), which may be desirable anyway.
  2. Add _tabs to ObjectTranslationDataSchema, keyed by tabs[].name, mirroring _views. Correct but needs a spec change plus console resolver support.
  3. Leave tab labels English by design and document it. Not viable for a localized product.

Priority note

Filed prio:p1 because of the Simplified Chinese customer trial: zh-CN is otherwise the most complete locale (32/32 navigation nodes, and after #660 the only locale with complete select-option coverage), so the English tab strip is now the most visible remaining i18n defect on a Chinese screen. Downgrade if the trial timeline says otherwise.

Full inventory

src/views/account.view.ts:88-94, campaign.view.ts:36-39, case.view.ts:50-56, contact.view.ts:38-40, contract.view.ts:38-41, forecast.view.ts:41-43, knowledge_article.view.ts:43-…, plus the remaining object view files — 59 labels total (grep -rn "tabs:" -A12 src/views/*.ts | grep -c "label: '").

Related: #494 (i18n umbrella), #645 (select option labels), #660 (zh-CN select options).

Activity

  1. added
    bugSomething isn't working
    metadataDeclarative metadata — schema, security posture, UI surfaces
    upstream:objectstackBlocked on / caused by the ObjectStack platform — tracked upstream
    on Aug 3, 2026
  2. self-assigned this
    on Aug 3, 2026
  3. yinlianghui commented on Aug 5, 2026

    @yinlianghui
    ContributorAuthor

    rc.2 retest: NOT reproduced — appears fixed

    Retested during the 17.0 GA acceptance sweep on @objectstack/* 17.0.0-rc.2 (current main, commit 5a78f88), read-only.

    List-view tab labels are translated in all three non-en locales on every list checked:

    Object zh-CN ja-JP es-ES
    crm_account 全部客户 / 客户卡片 / 客户地图 / 企业客户 全取引先 / 取引先カード / … Todas las Cuentas / …
    crm_opportunity translated translated translated
    crm_case 全部工单 / … translated translated

    Evidence: screenshots zh-CN-2-account-list.png, ja-JP-2-account-list.png, es-ES-2-account-list.png, *-2-oppty-list.png, plus the case-list tab dump in the run log.

    Recommend closing after the issue owner confirms — I am reporting the observation, not closing it, since the acceptance mandate for this run is test-don't-fix.

    One caveat worth recording: the create-form section tab strip (Case / SLA / Resolution on the New Case form) is still English in all locales including zh-CN and appears to have no translation key path at all. That is a different surface from this issue's list-view tabs, so I filed it separately as #683 rather than reopening the scope here.


    Generated by Claude Code

  4. yinlianghui commented on Aug 5, 2026

    @yinlianghui
    ContributorAuthor

    Independently confirmed fixed — and the issue body's core claim was wrong

    I filed this issue, so the correction is mine to make. Reproduced live against main (4888c4f) on @objectstack/* 17.0.0-rc.2, logged into the console at zh-CN, account list page:

    Tab bar renders 全部客户 / 客户卡片 / 客户地图 / 企业客户 / 还有 3 个. Not one inline tabs[].label appears — no "All", no "Cards", no "Map", no "Enterprise".

    That is the decisive detail. Those four Chinese strings exist only in zh-CN.ts under objects.crm_account._views.*.label, and the only path from a tab to them is tabs[].view. So the console resolves a tab's label by following its view reference to the referenced list view's translated label, and ignores the inline label when one resolves.

    That is exactly resolution 1 in the "Possible resolutions" list above — and it already existed. I listed it as an unverified hypothesis and said the renderer could not be checked, which was wrong in a way worth naming: I checked the public objectstack-ai/objectstack tree, found no console there, and stopped. The compiled console ships in node_modules/@objectstack/console and the app runs locally in one command. Behaviour was observable the whole time; I reasoned from schema source about a question only the renderer could answer.

    The practical consequence for this repo: the 59 inline English tabs[].label values are dead weight — overridden wherever the tab carries a view. Removing them is optional cleanup, not a fix.

    Recommend closing as fixed.

    One real gap, in the same toolbar but a different control

    Visible in the same screenshot, immediately right of the tab strip:

    [ Grid ] [ Gallery ] · 筛选 · 排序 · 视图设置

    The visualization switcher is English while every neighbouring control is translated. It comes from appearance.allowedVisualizations: ['grid', 'gallery', 'map'] (account.view.ts:85), which @objectstack/spec declares as a closed enum — map | tree | grid | kanban | gallery | calendar | timeline | gantt | chart — with no corresponding key anywhere in the translation schema. These are console-owned control labels, so no app bundle can reach them; this repo cannot fix it at any level of bundle completeness.

    That is the same defect class as objectstack-ai/objectstack#5083 (AddressField sub-labels are hardcoded English literals) — and it is what upstream objectstack-ai/objectstack#5377 should be about. #5377 currently argues that the tab bar is untranslatable, which this session's evidence contradicts; it needs rewriting or closing in favour of a visualization-switcher report. Two narrower points from it do survive: I18nLabelSchema's description still promises auto-generated i18n keys that do not exist for tabs[].label, and a tab declaring only a filter with no view has nothing to fall back to.

    For the record, all four locales are now at zero i18n warnings after #679, so the screenshot above is what a complete bundle looks like: everything app-authored is translated, and what remains English is platform-owned.


    Generated by Claude Code

  5. added
    priority:p1High: required for production / M2
    and removed on Sep 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

bugSomething isn't workingmetadataDeclarative metadata — schema, security posture, UI surfacespriority:p1High: required for production / M2upstream:objectstackBlocked on / caused by the ObjectStack platform — tracked upstream

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions