From 4e25db2989e40121a82b340d4dde3e826da3ad19 Mon Sep 17 00:00:00 2001 From: Daniel Dietzler <36593685+danieldietzler@users.noreply.github.com> Date: Mon, 6 Jul 2026 16:42:47 +0200 Subject: [PATCH] fix: chinese browser locales recognition (#29622) --- web/src/lib/i18n.spec.ts | 9 +++++++++ web/src/lib/utils/i18n.ts | 12 +++++++++++- 2 files changed, 20 insertions(+), 1 deletion(-) diff --git a/web/src/lib/i18n.spec.ts b/web/src/lib/i18n.spec.ts index ccc60a835b..ebf2fdfa3b 100644 --- a/web/src/lib/i18n.spec.ts +++ b/web/src/lib/i18n.spec.ts @@ -58,5 +58,14 @@ describe('i18n', () => { expect(getClosestAvailableLocale(['sr_Cyrl'], allLocales)).toBe('sr_Cyrl'); expect(getClosestAvailableLocale(['zh_Hant'], allLocales)).toBe('zh_Hant'); }); + + it('should handle language aliases', () => { + const allLocales = ['zh-Hans', 'zh-Hant']; + expect(getClosestAvailableLocale(['zh-CN'], allLocales)).toBe('zh-Hans'); + expect(getClosestAvailableLocale(['zh-HK'], allLocales)).toBe('zh-Hant'); + expect(getClosestAvailableLocale(['zh-MO'], allLocales)).toBe('zh-Hant'); + expect(getClosestAvailableLocale(['zh-SG'], allLocales)).toBe('zh-Hans'); + expect(getClosestAvailableLocale(['zh-TW'], allLocales)).toBe('zh-Hant'); + }); }); }); diff --git a/web/src/lib/utils/i18n.ts b/web/src/lib/utils/i18n.ts index 85331ddf7c..758721c384 100644 --- a/web/src/lib/utils/i18n.ts +++ b/web/src/lib/utils/i18n.ts @@ -13,6 +13,14 @@ export const getFormatter = async () => { return get(t); }; +const aliases: Record = { + 'zh-CN': 'zh-Hans', + 'zh-HK': 'zh-Hant', + 'zh-MO': 'zh-Hant', + 'zh-SG': 'zh-Hans', + 'zh-TW': 'zh-Hant', +}; + const modules = import.meta.glob('$i18n/*.json'); const fileCodes = Object.keys(modules) @@ -33,7 +41,9 @@ const getSubLocales = (locale: string) => { export const getClosestAvailableLocale = (locales: readonly string[], allLocales: readonly string[]) => { const allLocalesSet = new Set(allLocales.map((locale) => convertBCP47(locale))); - return locales.find((locale) => getSubLocales(locale).some((subLocale) => allLocalesSet.has(subLocale))); + return locales + .map((locale) => aliases[locale] ?? locale) + .find((locale) => getSubLocales(locale).some((subLocale) => allLocalesSet.has(subLocale))); }; export const getPreferredLocale = () => getClosestAvailableLocale(navigator.languages, langCodes);