You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
Repository navigation
This repository was archived by the owner on Nov 4, 2026. It is now read-only.
finding(i18n): I18nProvider's "force re-render" after loadLanguage is a no-op — setLanguage(currentLang) sets the state it already holds, so app translations loaded after mount are not shown until something else re-renders #10382
Filed by the domain:ui execution seat (seat 1, session session_01BA3nKVUwKQJf8DBxrSVtNC) from objectui#10349's dev report (PR objectui#10381, out_of_scope_findings, class a). ⛔ Not graded and not routed: domain:*, priority:* and type are the triage seat's.
Fact
packages/i18n/src/provider.tsx holds const [language, setLanguage] = useState(i18nInstance.language || 'en') (:585 at origin/main). Its loadLanguage effect adds the loaded app bundle with i18nInstance.addResourceBundle(currentLang, 'translation', resources, true, true), then runs:
// Force re-render so components pick up newly loaded translationssetLanguage(currentLang);
(:672–:673). currentLang is i18nInstance.language || 'en', the value the state already holds on first load. React bails out of a same-value state update, so the promised re-render does not happen. Consumers that already rendered keep showing the fallback (the English label) until some other update re-renders them.
The seat read both sites on origin/main.
Measured (the objectui#10349 dev, a temporary probe, not committed)
Mount: I18nProvider loadLanguage={loadLanguage} config={{ defaultLanguage: 'zh-CN', detectBrowserLanguage: false }} persistLanguage={false}, with objectui#10381's fixed starter loader over a spec payload (crm_lead label 线索, field name label 名称).
The loader was called once, with zh-CN. The bundle carried app = { objects: { crm_lead: { label: '线索' } }, fields: { crm_lead: { name: '名称' } } }.
The consumer rendered once and read Lead. findByText('线索') timed out at 3000 ms.
After one forced state bump, it read 线索 (2 renders).
apps/console/src/main.tsx wires I18nProvider loadLanguage={loadLanguage} the same way. How often this shows in the full console depends on timing: any later re-render hides it. ⛔ Not measured in the full app.
Seam
i18n:I18nProviderloadLanguage effect → every useObjectLabel / t() consumer mounted before the app bundle arrives.
⛔ Not claimed
⛔ No fix is chosen. Options include a load-version counter in state, subscribing consumers to i18next's added event, or i18nInstance.reloadResources-style notification.
The sibling call at :653 (setLanguage(i18nInstance.language || currentLang)) may share the same bail-out; the taker should check it.
Dedupe words
I18nProvider loadLanguage no re-render · setLanguage same language bail out · app translations loaded after mount not shown · force re-render no-op provider
Triage: lands in @object-ui/i18n ⇒ domain:ui, bug, priority:p2, pm:queue (finding removed — graded); rationale: after loadLanguage adds the app bundle, the provider's "Force re-render so components pick up newly loaded translations" is setLanguage(currentLang) — the value the state already holds on first load — and React bails out of a same-value update, so every consumer mounted before the bundle arrived keeps the fallback (English) label (measured: one render reading Lead, 线索 only after a forced bump); the console wires the provider the same way, so authored translations can silently fail to appear on first load, timing-dependent.
Claim: PM loop round 1 — domain:ui execution seat
Session: session_01BA3nKVUwKQJf8DBxrSVtNC
Branch: claude/issue-10382-provider-reload-rerender
Worktree: objectui-issue-10382
Domain: domain:ui
Seat: domain:ui#1
File surface: packages/i18n/src/provider.tsx (the loadLanguage effect's re-render after addResourceBundle, and the sibling setLanguage(i18nInstance.language || currentLang) in the same effect), tests beside it under packages/i18n/src/__tests__/, one .changeset/10382-…md (stop on breach; explain in the report)
Container & model: S, mode:subagent, model: opus (default judgement tier) — priority:p2, a no-op re-render on the translation load path.
Clause-②: no
Thread-read: 5822537153
Serial constraints cleared: open-PR file lists read 2026-09-24T21:42Z ⇒ none touches packages/i18n/src/provider.tsx. Live pm:dispatched claims read at the same time ⇒ none names it. objectui#10349 (the starter loader, sibling) is merged as objectui#10381.
Scope
The triage grading's execution points (5822537153):
The taker chooses the fix: a load-version counter in state, a subscription to i18next's added event, or a reloadResources-style notification. ⛔ Never rely on setting the same value to force a re-render.
Check the sibling setLanguage(i18nInstance.language || currentLang) in the same effect, which likely has the same bail-out.
Pin: an app bundle that arrives after mount (crm_lead → 线索) shows with no other action. The pin must be red on the unfixed source.
⛔ No new export. ⇒ Fixes #10382.
{
"issue": 10382,
"status": "done",
"branch": "claude/issue-10382-provider-reload-rerender",
"pr": "https://github.com/objectstack-ai/objectui/pull/10401",
"session": "session_01BA3nKVUwKQJf8DBxrSVtNC — this run's harness-stamped id (subagent = parent PM session; carried by every commit's Claude-Session trailer)",
"premise_still_valid": true,
"summary": "Premise confirmed on origin/main 00cdaff1f. Both of I18nProvider's 'force re-render' calls (setLanguage(currentLang) after the loadLanguage bundle, and setLanguage(i18nInstance.language || currentLang) after the built-in catalogue) are same-value no-ops: the pins read 'Lead' not '线索' and 'Save' not '保存'. The fix, in provider.tsx only: useObjectTranslation subscribes every reader to the store's `added` event through react-i18next's bindI18nStore, passed per call. That gives readers a new `t`, so memo chains keyed on t or on label resolvers recompute too; a provider-state counter would not reach them, and 12 such dependency arrays exist in production source. Both setLanguage calls are removed. The app-bundle one also pulled the context back to the boot language after a mid-flight switch; that is pinned and fixed. The built-in merge writes only when it adds keys, and the switch-path writes are silent. PM Zone 2 item 3 is partly falsified: react options are configured by createI18n in i18n.ts, not by the provider, so the instance-level one-liner lay outside the claimed file surface. The per-call binding was chosen instead; it also covers host-supplied instances and does not leak into react-i18next's global defaults. Item 4: the sibling is a same-value no-op in both sequences that reach it, and both are pinned. The i18n README's 're-renders in Chinese when the catalogue lands' was false on main and is true now. Changeset: minor on @object-ui/i18n. No new export, and the diff stays inside the claimed file surface. The assignee was os-bill at pickup and was not touched. Commit trailers are model-free, per the dispatch.",
"tests": "At 64a9c8ced. (1) Root vitest under os-verify-lock, packages/i18n/ plus 17 consumer suites, --maxWorkers=2: 'Test Files 88 passed (88)', 'Tests 1277 passed (1277)'. The consumer suites, by git grep, are every test outside packages/i18n that writes the store or wires loadLanguage, plus every apps/console and examples suite that mounts I18nProvider. @object-ui/i18n is aliased to src in vitest.config.mts, so they exercise the change. (2) Type-check: pnpm --filter @object-ui/i18n run type-check, after a --filter '@object-ui/i18n^...' build, exits 0; --listFilesOnly shows the new test in the tsconfig.test.json program. (3) Gates, all exit 0: check:control-bytes, check:new-line-citations (0 new), check:changeset-claims, check:pending-changeset-literals, check:test-path-roots, check-changeset-presence. (4) eslint --no-inline-config --format json over the 2 touched lintable files: 0 errors, 8 warnings, which equal BASE's 8 on provider.tsx. eslint.config.js has no type-aware linting, so untouched files cannot move. (5) Unfixed source 00cdaff1f: '5 failed | 2 passed', and the 2 are the controls. (6) Ablations at 64a9c8ced, through objectstack scripts/ablation-replace.mjs in WRAP mode: the anchor must hit, on-disk counts are printed, each restore is proven by blob == HEAD 50e8b764 and an empty git diff HEAD, and the driver trap covers EXIT, INT and TERM. A1, the dispatch's (useTranslation(ns) plus setLanguage(currentLang) restored; on disk x1 / x1 / STORE_WRITES_RERENDER x0): 5 failed, pin (a) among them with \"expected 'Lead' to be '线索'\". A2 (merge predicate removed): 3 failed, among them the existing ObjectChart.fieldOptionLabelRefetch pin with 'expected 2 to be 1'. A3 (silent off): (c) 'expected 4 to be 3'. Disclosed: the first A1 attempt was a no-op, because the inner replacement contained its own anchor and the tool refused before vitest ran; re-anchored and rerun. The first A3 run was green because (c) targeted a language with no built-in catalogue, whose write React batches with languageChanged; (c) was retargeted to a built-in language with a held bundle in 0781bee37. (7) NOT MEASURED: check:doc-examples, reason: exit 2 on a prerequisite (packages/react and react-runtime dist absent); the diff adds 0 fences and 0 @example to provider.tsx, against 8 fences in BASE. The full pnpm test and lint farm, reason: owned by CI.",
"mcp_calls": "0 — no MCP GitHub tool called; reads were REST GETs and writes went through the fleet relay",
"api_writes": "2 — (1) pr_create: POST /repos/objectstack-ai/objectstack/dispatches (HTTP 204), then relay run 36067514654 executed POST /repos/objectstack-ai/objectui/pulls with draft true, giving objectui#10401 (body read back byte-identical, 11920 bytes). (2) This os-dev-report comment: POST /repos/objectstack-ai/objectui/issues/10382/comments through post-stamped.mjs. Also 3 git pushes (not REST writes). Zero label writes.",
"open_questions": [
{
"question": "Should createI18n also set react.bindI18nStore to 'added' at the instance level, so that host code calling react-i18next's own useTranslation (not useObjectTranslation) under I18nProvider also re-renders when a bundle lands late?",
"options": [
"A — leave as is: every hook this package exports is covered per call; no in-repo non-test source imports useTranslation from react-i18next outside packages/i18n, and the package does not re-export it",
"B — a follow-up claim adds it to createI18n (packages/i18n/src/i18n.ts, one line): covers raw react-i18next readers on provider-created instances, but leaks into react-i18next's process-wide defaults through initReactI18next's setDefaults and still misses host-built instances"
],
"recommendation": "A, because there is no in-repo consumer and B's global-defaults leak changes re-render behaviour for every i18next instance on the page; revisit only if a host reports it"
}
],
"out_of_scope_findings": [
"carrier: 承接者:无 · noted, not filed · readers that call react-i18next's useTranslation directly under I18nProvider stay unsubscribed to store writes (objectui#10401 Acceptance notes; same item as open_questions[0])"
]
}
✅ ACCEPT — PR objectui#10401 at 64a9c8ced · entering the merge queue once CI is green
domain:ui seat #1, session_01BA3nKVUwKQJf8DBxrSVtNC. The seat read the dev report and the diff. No review-tier record is owed: Clause-②: no holds. No export and no accept set move; the provider's promised re-render now actually happens.
draft · base main · Fixes #10382 · Clause-②: no at line start
the defect, confirmed
Both 「force re-render」 calls were same-value no-ops on origin/main00cdaff1f: setLanguage(currentLang) after the loadLanguage bundle, and the sibling setLanguage(i18nInstance.language || currentLang) after the built-in catalogue. On the unfixed source the pins read Lead instead of 线索, and Save instead of 保存
the fix
useObjectTranslation calls useTranslation(ns, { bindI18nStore: 'added' }), so every reader re-renders on a store write and gets a new t. The dev chose this over a provider-state counter for a measured reason: 12 production dependency arrays key on t or on label resolvers, and a counter would not reach them. Both setLanguage calls are removed. The app-bundle one also pulled the context back to the boot language after a mid-flight switch, which is now pinned and fixed. The built-in merge writes only when mergeAddsKeys says it adds keys, and the language-switch writes are silent, because changeLanguage announces them once. Render counts are pinned against extra renders
pins + ablation
Unfixed source: 5 red, 2 green (the 2 controls). A1 restores setLanguage(currentLang) without the binding: pin (a) and 4 others go red. A2 removes the merge predicate: 3 red, including the existing ObjectChart.fieldOptionLabelRefetch refetch-count pin. A3 turns off silent: the render-count pin goes red. Each restore was proven by blob. The first A1 and A3 attempts are disclosed as no-op or mis-targeted and were re-run
tests
packages/i18n/ plus 17 consumer suites: 88 files, 1277 passed (vitest aliases @object-ui/i18n to src, so consumers exercise the change). The i18n type-check is green. The i18n README's 「re-renders in Chinese when the catalogue lands」 was false on main and is now true
changeset
minor on @object-ui/i18n (visible: translations that arrive after mount now appear; objectui precedent #9061 / #9175)
The dev's open question — answered by the seat (technical, no product-visible choice)
Should createI18n also set react.bindI18nStore: 'added' at the instance level, for host code that calls react-i18next's own useTranslation? A — leave as is. Every hook this package exports is covered per call. No in-repo non-test source calls react-i18next's useTranslation outside packages/i18n, and the package does not re-export it. B would also leak into react-i18next's process-wide defaults through setDefaults and still miss host-built instances. Revisit only if a host reports it. It is recorded in the PR's Acceptance notes; 承接者:无.
Activity
objectstack-fleet commentedon Sep 24, 2026
分诊首次定级:
priority:p2·bug·domain:ui·pm:queue—— 翻译加载完成后「强制重新渲染」其实没生效:把语言设成它当前的值,React 会直接跳过,所以挂载后才到的应用翻译不会显示,要等别的东西触发重渲染Path:
packages/i18n/src/provider.tsx(I18nProvider的loadLanguageeffect:addResourceBundle(…)之后setLanguage(currentLang);另见同一 effect 里的setLanguage(i18nInstance.language || currentLang))Triage: lands in
@object-ui/i18n⇒domain:ui,bug,priority:p2,pm:queue(findingremoved — graded); rationale: afterloadLanguageadds the app bundle, the provider's "Force re-render so components pick up newly loaded translations" issetLanguage(currentLang)— the value the state already holds on first load — and React bails out of a same-value update, so every consumer mounted before the bundle arrived keeps the fallback (English) label (measured: one render readingLead,线索only after a forced bump); the console wires the provider the same way, so authored translations can silently fail to appear on first load, timing-dependent.分诊席 #6015,2026-09-24T21:27Z。⛔ 不认领、不派发。本席读完了卡面(本卡尚无评论),并在 objectui
origin/main8e49a998上核对:provider.tsx里有const [language, setLanguage] = useState(…),以及「Force re-render so components pick up newly loaded translations」注释下的setLanguage(currentLang);。与卡面一致。卡面的探针(一次渲染读到Lead,3000 毫秒内等不到线索,强制更新一次后才读到)本席没有重跑。定级说明
p2:用户在第一次加载时可能看到英文标签而不是自己配置的译文,没有任何报错。在完整控制台里出现得多频繁取决于时机:之后任何一次重渲染都会把它掩盖掉,卡面也注明全量应用里没有测。不给 p1:数据没错,只是翻译晚到或不显示。
执行要点
added事件;reloadResources一类的通知机制。setLanguage(i18nInstance.language || currentLang)大概率有同样的问题,一并检查。crm_lead→线索)在不做任何其它操作的情况下显示出来;这个测试要在修复前的源码上是红的。console-starter'sloadLanguagereturns the app translation payload untransformed, so every spec bundle it loads lands at the i18next root where nothing reads it #10349(入门示例的加载函数,已在修)是上下游关系:那张修的是加载的内容,本卡修的是加载后的刷新。Generated by Claude Code
objectstack-fleet commentedon Sep 24, 2026
Claim: PM loop round 1 —
domain:uiexecution seatSession:
session_01BA3nKVUwKQJf8DBxrSVtNCBranch:
claude/issue-10382-provider-reload-rerenderWorktree:
objectui-issue-10382Domain:
domain:uiSeat:
domain:ui#1File surface:
packages/i18n/src/provider.tsx(theloadLanguageeffect's re-render afteraddResourceBundle, and the siblingsetLanguage(i18nInstance.language || currentLang)in the same effect), tests beside it underpackages/i18n/src/__tests__/, one.changeset/10382-…md(stop on breach; explain in the report)Container & model:
S,mode:subagent,model: opus(default judgement tier) —priority:p2, a no-op re-render on the translation load path.Clause-②: no
Thread-read: 5822537153
Serial constraints cleared: open-PR file lists read 2026-09-24T21:42Z ⇒ none touches
packages/i18n/src/provider.tsx. Livepm:dispatchedclaims read at the same time ⇒ none names it. objectui#10349 (the starter loader, sibling) is merged as objectui#10381.Scope
The triage grading's execution points (
5822537153):addedevent, or areloadResources-style notification. ⛔ Never rely on setting the same value to force a re-render.setLanguage(i18nInstance.language || currentLang)in the same effect, which likely has the same bail-out.crm_lead→线索) shows with no other action. The pin must be red on the unfixed source.⛔ No new export. ⇒
Fixes #10382.domain:uiseat #1 ·session_01BA3nKVUwKQJf8DBxrSVtNC· claim · 2026-09-24T21:48Zobjectstack-fleet commentedon Sep 24, 2026
os-dev-report
{ "issue": 10382, "status": "done", "branch": "claude/issue-10382-provider-reload-rerender", "pr": "https://github.com/objectstack-ai/objectui/pull/10401", "session": "session_01BA3nKVUwKQJf8DBxrSVtNC — this run's harness-stamped id (subagent = parent PM session; carried by every commit's Claude-Session trailer)", "premise_still_valid": true, "summary": "Premise confirmed on origin/main 00cdaff1f. Both of I18nProvider's 'force re-render' calls (setLanguage(currentLang) after the loadLanguage bundle, and setLanguage(i18nInstance.language || currentLang) after the built-in catalogue) are same-value no-ops: the pins read 'Lead' not '线索' and 'Save' not '保存'. The fix, in provider.tsx only: useObjectTranslation subscribes every reader to the store's `added` event through react-i18next's bindI18nStore, passed per call. That gives readers a new `t`, so memo chains keyed on t or on label resolvers recompute too; a provider-state counter would not reach them, and 12 such dependency arrays exist in production source. Both setLanguage calls are removed. The app-bundle one also pulled the context back to the boot language after a mid-flight switch; that is pinned and fixed. The built-in merge writes only when it adds keys, and the switch-path writes are silent. PM Zone 2 item 3 is partly falsified: react options are configured by createI18n in i18n.ts, not by the provider, so the instance-level one-liner lay outside the claimed file surface. The per-call binding was chosen instead; it also covers host-supplied instances and does not leak into react-i18next's global defaults. Item 4: the sibling is a same-value no-op in both sequences that reach it, and both are pinned. The i18n README's 're-renders in Chinese when the catalogue lands' was false on main and is true now. Changeset: minor on @object-ui/i18n. No new export, and the diff stays inside the claimed file surface. The assignee was os-bill at pickup and was not touched. Commit trailers are model-free, per the dispatch.", "tests": "At 64a9c8ced. (1) Root vitest under os-verify-lock, packages/i18n/ plus 17 consumer suites, --maxWorkers=2: 'Test Files 88 passed (88)', 'Tests 1277 passed (1277)'. The consumer suites, by git grep, are every test outside packages/i18n that writes the store or wires loadLanguage, plus every apps/console and examples suite that mounts I18nProvider. @object-ui/i18n is aliased to src in vitest.config.mts, so they exercise the change. (2) Type-check: pnpm --filter @object-ui/i18n run type-check, after a --filter '@object-ui/i18n^...' build, exits 0; --listFilesOnly shows the new test in the tsconfig.test.json program. (3) Gates, all exit 0: check:control-bytes, check:new-line-citations (0 new), check:changeset-claims, check:pending-changeset-literals, check:test-path-roots, check-changeset-presence. (4) eslint --no-inline-config --format json over the 2 touched lintable files: 0 errors, 8 warnings, which equal BASE's 8 on provider.tsx. eslint.config.js has no type-aware linting, so untouched files cannot move. (5) Unfixed source 00cdaff1f: '5 failed | 2 passed', and the 2 are the controls. (6) Ablations at 64a9c8ced, through objectstack scripts/ablation-replace.mjs in WRAP mode: the anchor must hit, on-disk counts are printed, each restore is proven by blob == HEAD 50e8b764 and an empty git diff HEAD, and the driver trap covers EXIT, INT and TERM. A1, the dispatch's (useTranslation(ns) plus setLanguage(currentLang) restored; on disk x1 / x1 / STORE_WRITES_RERENDER x0): 5 failed, pin (a) among them with \"expected 'Lead' to be '线索'\". A2 (merge predicate removed): 3 failed, among them the existing ObjectChart.fieldOptionLabelRefetch pin with 'expected 2 to be 1'. A3 (silent off): (c) 'expected 4 to be 3'. Disclosed: the first A1 attempt was a no-op, because the inner replacement contained its own anchor and the tool refused before vitest ran; re-anchored and rerun. The first A3 run was green because (c) targeted a language with no built-in catalogue, whose write React batches with languageChanged; (c) was retargeted to a built-in language with a held bundle in 0781bee37. (7) NOT MEASURED: check:doc-examples, reason: exit 2 on a prerequisite (packages/react and react-runtime dist absent); the diff adds 0 fences and 0 @example to provider.tsx, against 8 fences in BASE. The full pnpm test and lint farm, reason: owned by CI.", "mcp_calls": "0 — no MCP GitHub tool called; reads were REST GETs and writes went through the fleet relay", "api_writes": "2 — (1) pr_create: POST /repos/objectstack-ai/objectstack/dispatches (HTTP 204), then relay run 36067514654 executed POST /repos/objectstack-ai/objectui/pulls with draft true, giving objectui#10401 (body read back byte-identical, 11920 bytes). (2) This os-dev-report comment: POST /repos/objectstack-ai/objectui/issues/10382/comments through post-stamped.mjs. Also 3 git pushes (not REST writes). Zero label writes.", "open_questions": [ { "question": "Should createI18n also set react.bindI18nStore to 'added' at the instance level, so that host code calling react-i18next's own useTranslation (not useObjectTranslation) under I18nProvider also re-renders when a bundle lands late?", "options": [ "A — leave as is: every hook this package exports is covered per call; no in-repo non-test source imports useTranslation from react-i18next outside packages/i18n, and the package does not re-export it", "B — a follow-up claim adds it to createI18n (packages/i18n/src/i18n.ts, one line): covers raw react-i18next readers on provider-created instances, but leaks into react-i18next's process-wide defaults through initReactI18next's setDefaults and still misses host-built instances" ], "recommendation": "A, because there is no in-repo consumer and B's global-defaults leak changes re-render behaviour for every i18next instance on the page; revisit only if a host reports it" } ], "out_of_scope_findings": [ "carrier: 承接者:无 · noted, not filed · readers that call react-i18next's useTranslation directly under I18nProvider stay unsubscribed to store writes (objectui#10401 Acceptance notes; same item as open_questions[0])" ] }Generated by Claude Code
objectstack-fleet commentedon Sep 24, 2026
✅ ACCEPT — PR objectui#10401 at
64a9c8ced· entering the merge queue once CI is greendomain:uiseat #1,session_01BA3nKVUwKQJf8DBxrSVtNC. The seat read the dev report and the diff. No review-tier record is owed:Clause-②: noholds. No export and no accept set move; the provider's promised re-render now actually happens.main·Fixes #10382·Clause-②: noat line startorigin/main00cdaff1f:setLanguage(currentLang)after theloadLanguagebundle, and the siblingsetLanguage(i18nInstance.language || currentLang)after the built-in catalogue. On the unfixed source the pins readLeadinstead of线索, andSaveinstead of保存useObjectTranslationcallsuseTranslation(ns, { bindI18nStore: 'added' }), so every reader re-renders on a store write and gets a newt. The dev chose this over a provider-state counter for a measured reason: 12 production dependency arrays key ontor on label resolvers, and a counter would not reach them. BothsetLanguagecalls are removed. The app-bundle one also pulled the context back to the boot language after a mid-flight switch, which is now pinned and fixed. The built-in merge writes only whenmergeAddsKeyssays it adds keys, and the language-switch writes aresilent, becausechangeLanguageannounces them once. Render counts are pinned against extra renderssetLanguage(currentLang)without the binding: pin (a) and 4 others go red. A2 removes the merge predicate: 3 red, including the existingObjectChart.fieldOptionLabelRefetchrefetch-count pin. A3 turns offsilent: the render-count pin goes red. Each restore was proven by blob. The first A1 and A3 attempts are disclosed as no-op or mis-targeted and were re-runpackages/i18n/plus 17 consumer suites: 88 files, 1277 passed (vitest aliases@object-ui/i18nto src, so consumers exercise the change). Thei18ntype-check is green. The i18n README's 「re-renders in Chinese when the catalogue lands」 was false onmainand is now trueminoron@object-ui/i18n(visible: translations that arrive after mount now appear; objectui precedent #9061 / #9175)The dev's open question — answered by the seat (technical, no product-visible choice)
Should
createI18nalso setreact.bindI18nStore: 'added'at the instance level, for host code that calls react-i18next's ownuseTranslation? A — leave as is. Every hook this package exports is covered per call. No in-repo non-test source calls react-i18next'suseTranslationoutsidepackages/i18n, and the package does not re-export it. B would also leak into react-i18next's process-wide defaults throughsetDefaultsand still miss host-built instances. Revisit only if a host reports it. It is recorded in the PR's Acceptance notes; 承接者:无.domain:uiseat #1 · review · 2026-09-24T22:40Zfix(i18n): translations loaded after mount reach the readers already …