This repository was archived by the owner on Oct 26, 2026. It is now read-only.
Repository navigation
fix(app-shell,components): resolve a page's inline locale label and description to the viewer's language (objectui#13488) - #13501
Merged
Conversation
…l in the app bar title (objectui#13488) The page and dashboard branches of AppHeader handed a served `label` to the phone bar's title unresolved. `PageSchema.label` and `DashboardSchema.label` are `string | I18nLabel`, so an inline locale map reached JSX and React refused it (error #31), blanking the route. Both now resolve through `metadataText` in the viewer's language, as the report branch does since objectui#13470. Claude-Session: https://claude.ai/code/session_012oUFcAgU5BgTKe6fa7RxD8 Co-authored-by: Claude <noreply@anthropic.com>
… in its own heading (objectui#13488) `PageRenderer` drew a page's `label` as its implicit h1 and its `description` under it raw, and handed the raw description to a titled `page:header`. Both are `I18nLabel` in `PageSchema`, so an inline locale map reached JSX and React refused it (error #31). They now resolve through `pickLocalized` in the viewer's language, as `page:header` resolves its own title. One changeset covers this and the app bar fix. Claude-Session: https://claude.ai/code/session_012oUFcAgU5BgTKe6fa7RxD8 Co-authored-by: Claude <noreply@anthropic.com>
The inline-locale page fixture arrives as data, so it is cast once to the `SchemaRenderer` prop type instead of through `any`. Claude-Session: https://claude.ai/code/session_012oUFcAgU5BgTKe6fa7RxD8 Co-authored-by: Claude <noreply@anthropic.com>
Contributor
✅ Console Performance Budget
The eager closure is every chunk the entry reaches through static imports — what the browser fetches and parses before the app renders. The entry chunk on its own is a small fraction of it. 📦 Bundle Size Report
Size Limits
|
Contributor
Author
席位核对 — ACCEPT · PR #13501 @
|
This was referenced Oct 26, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Requested by Elon · project thread
Fixes #13488
Clause-②: no
Metadata-protocol: none
What changed
PageSchemain@objectstack/spectypes a page'slabelanddescriptionasI18nLabel, so an inline locale map such as{ 'zh-CN', en }is valid metadata, and the/metaread serves it unchanged. Two packages drew it raw on a page route, and React refused the object as a child (error #31), so the route was blank for every viewer:@object-ui/app-shell,AppHeader's page branch. It handed the served label topageLabelas its fallback, andpageLabelreturns an unmatched fallback untouched, so the map became the phone bar's title. It now resolves throughmetadataTextin the viewer's language (useObjectTranslation().language), the call the report branch has used since objectui#13470, and still passes through thepages.NAME.labelbundle lookup. The humanized slug stays the fallback when no label resolves.@object-ui/components,PageRenderer. The page's own implicit heading (schema.title ?? schema.label), the line under it (schema.description), and the description it hands a titledpage:headerthroughPageDescriptionContextwere all drawn raw. Each now resolves throughpickLocalizedin the viewer's language, the resolverpage:headeralready uses for its own title in the same package. With only the app bar fixed, anapp,homeorutilitypage with a map label stayed blank through this heading (measured, below), so the claim was widened to this file (claim amendment on App page route goes blank (React error #31) when a page's label is the spec's inline locale map (I18nLabel { zh-CN, en }) #13488).AppHeader's dashboard branch drew a served dashboard label straight into the phone bar's title.DashboardSchema.labelisI18nLabeltoo, so it is nowmetadataText(…) ?? dashboardLabel(…).A plain-string label or description draws exactly as before:
metadataTextandpickLocalizedboth pass a string through, and an empty one still falls to the slug or hides the description. Studio's page previews (SourcePageEditor,PagePreview) render through the samePageRenderer, so they get the fix too. One changeset:@object-ui/app-shelland@object-ui/componentspatch.Tests
New pins, each mounting the real component under a real
I18nProvider, each leg inenandzh-CNreading different strings out of one map, with plain strings as the control:packages/app-shell/src/layout/__tests__/AppHeader.pageDashboardTitleInlineLocale-13488.test.tsx: theAppHeader.reportCrumbInlineLocale-13470harness withuseObjectLabelreal. LegsPAGE_LABEL_MAP_RESOLVES,DASHBOARD_LABEL_MAP_RESOLVES, twoPLAIN_STRING_CONTROLs.packages/components/src/__tests__/page-inline-locale-label-13488.test.tsx: anapppage through the realSchemaRendererandPageRenderer. LegsHEADING_MAP_RESOLVES,DESCRIPTION_MAP_RESOLVES,HEADER_DESCRIPTION_MAP_RESOLVES(titledpage:header),PLAIN_STRING_CONTROL.Readings, final head
2c82e03unless stated:AppHeader,PageView,PageRenderer,SourcePageEditor,PagePrevieworpageKindNode, plus everypackages/componentstest that namesPageRenderer,page:header,pageType, the page renderer module or anapp/home/utilitypage node (212 files, found bygit grep -lEover test files), withpnpm exec vitest run --maxWorkers=2: Test Files 212 passed (212), Tests 2161 passed (2161). Run atbf37518; the only later commit,2c82e03, changes the type annotation of one new test's fixture, and both new files were re-run at2c82e03above.turbo run type-check --filter=@object-ui/app-shell --filter=@object-ui/components --concurrency=2 --continue: 31 successful, 31 total. Both packages'type-checkchaintsconfig.test.json, so the new test files are type-checked.page.tsxis the(schema as any).labelread the old line already had.node scripts/check-changeset-presence.mjs: pass (4 source files of 2 released packages, 1 changeset).node scripts/check-changeset-no-major.mjs: pass.pnpm check:new-line-citations: 0 new citations.Narrowed, declared: the whole
packages/app-shell/andpackages/components/suites were not run locally; CI's shardedpnpm testruns them. The narrowed set's blind spot is a test that mounts these components through another import path without naming them.Probe before the fix, on main
85b6a48, through the realSchemaRendererandPageRenderer(a throwaway file, not committed): anapppage with a maplabel, one with a mapdescription, and one with a titledpage:headerand a mapdescriptionall failed onObjects are not valid as a React child (found: object with keys {zh-CN, en}).Ablation, one site at a time on the committed fix, through
scripts/ablation-replace.mjs(anchor must hit once, blob must change, restore proven by blob equal toHEADand an emptygit diff HEAD), running the two new files each time:pageDef?.label || humanizeSlug(pageName)): 2 failed, 14 passed. OnlyPAGE_LABEL_MAP_RESOLVESfails, in both languages, on React error Task: Refactor Monorepo to Support Lazy-Loaded Plugins #31.dashboardDef?.label || dashboardLabel(…)): 2 failed, 14 passed. OnlyDASHBOARD_LABEL_MAP_RESOLVESfails, on the same error.PageRendererheading reverted (schema.title ?? schema.labelraw): 2 failed, 14 passed. OnlyHEADING_MAP_RESOLVESfails, on the same error.PageRendererdescription reverted (rawschema.description): 4 failed, 12 passed.DESCRIPTION_MAP_RESOLVESandHEADER_DESCRIPTION_MAP_RESOLVESfail, on the same error.Acceptance notes
InterfaceListPage(an interface page's list surface) readstypeof page.label === 'string' ? page.label : page.namefor its heading and its record drawer's title, and drawspage.descriptiononly when it is a string. A page with a map label does not blank there, but it shows the page's machine name instead of its label, and a map description is not shown. Read from the code on85b6a48, not measured; outside this claim's file surface. Handed to the seat.AppHeader's view branch handsviewDef?.label || viewDef?.titletoviewTabLabel, and a list view'slabelisI18nLabelin the spec as well. The object page's tab bar (ObjectView) hands the same label to the same function, so whether a map view label blanks a view route is a question aboutObjectView, not this header alone. Read from the code, not measured; not changed here.pages.NAME.labelbundle lookup, while the page's own heading draws the served label. That split predates this PR and is unchanged, as on the report route.🤖 Generated with Claude Code
https://claude.ai/code/session_012oUFcAgU5BgTKe6fa7RxD8