From fd24b354498db5cf8b74606949dd564bf9a77f83 Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Tue, 24 Feb 2026 03:51:31 +0000 Subject: [PATCH] fix: cover startup locale hydration path (#24795) (thanks @chilu18) --- CHANGELOG.md | 1 + ui/src/i18n/test/translate.test.ts | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index dc238731349..fe7ba34ffb5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Docs: https://docs.openclaw.ai ### Fixes +- Web UI/i18n: load and hydrate saved locale translations during startup so non-English sessions apply immediately without manual toggling. (#24795) Thanks @chilu18. - Plugins/Config schema: support legacy plugin schemas without `toJSONSchema()` by falling back to permissive object schema generation. (#24933) Thanks @pandego. - Cron/Isolated sessions: use full prompt mode for isolated cron runs so skills/extensions are available during cron execution. (#24944) - Discord/Reasoning: suppress reasoning/thinking-only payload blocks from Discord delivery output. (#24969) diff --git a/ui/src/i18n/test/translate.test.ts b/ui/src/i18n/test/translate.test.ts index b06aa8d2d23..178fd12b1e3 100644 --- a/ui/src/i18n/test/translate.test.ts +++ b/ui/src/i18n/test/translate.test.ts @@ -1,4 +1,4 @@ -import { describe, it, expect, beforeEach } from "vitest"; +import { describe, it, expect, beforeEach, vi } from "vitest"; import { i18n, t } from "../lib/translate.ts"; describe("i18n", () => { @@ -40,4 +40,17 @@ describe("i18n", () => { await i18n.setLocale("zh-CN"); expect(t("common.health")).toBe("健康状况"); }); + + it("loads saved non-English locale on startup", async () => { + localStorage.setItem("openclaw.i18n.locale", "zh-CN"); + vi.resetModules(); + const fresh = await import("../lib/translate.ts"); + + for (let index = 0; index < 5 && fresh.i18n.getLocale() !== "zh-CN"; index += 1) { + await Promise.resolve(); + } + + expect(fresh.i18n.getLocale()).toBe("zh-CN"); + expect(fresh.t("common.health")).toBe("健康状况"); + }); });