Commit becc18e3 by CaIon

fix(i18n): add language detection mapping for Chinese locales

parent 8f31b305
......@@ -20,6 +20,7 @@ import i18n from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector'
import { initReactI18next } from 'react-i18next'
import { convertDetectedLanguage } from './languages'
import en from './locales/en.json'
import fr from './locales/fr.json'
import ja from './locales/ja.json'
......@@ -44,8 +45,8 @@ i18n
.init({
resources,
fallbackLng: 'en',
supportedLngs: ['en', 'zhCN', 'fr', 'ru', 'ja', 'vi','zhTW'],
load: 'currentOnly', // Convert zh-CN -> zh
supportedLngs: ['en', 'zhCN', 'fr', 'ru', 'ja', 'vi', 'zhTW'],
load: 'currentOnly',
nsSeparator: false, // Allow literal colons in keys (e.g., URLs, labels)
debug: import.meta.env.DEV,
interpolation: {
......@@ -54,6 +55,9 @@ i18n
detection: {
order: ['localStorage', 'navigator'],
caches: ['localStorage'],
// Browsers report `zh-CN`/`zh-TW`/`zh`; map them onto our `zhCN`/`zhTW`
// codes (non-Chinese codes pass through for normal supportedLngs matching).
convertDetectedLanguage,
},
})
......
......@@ -33,7 +33,7 @@ export type InterfaceLanguageCode =
export function normalizeInterfaceLanguage(value?: string | null): string {
if (!value) return 'en'
var normalized = value.trim().replace(/_/g, '-').toLowerCase()
let normalized = value.trim().replaceAll('_', '-').toLowerCase()
if (value === 'zh-TW' || value === 'zh-HK' || value === 'zh-MO' || value === 'zhTW') {
normalized = 'zhTW'
}
......@@ -47,6 +47,30 @@ export function normalizeInterfaceLanguage(value?: string | null): string {
}
/**
* Map a browser-detected locale onto the interface language codes this project
* uses with i18next (`zhCN` / `zhTW`).
*
* Browsers report standard BCP-47 tags (`zh-CN`, `zh-TW`, `zh-Hant`, `zh`, ...),
* but `supportedLngs`/resources use the non-standard camelCase codes, so without
* this mapping a Chinese browser would never match and fall back to English.
* Non-Chinese codes are returned unchanged so i18next's own `supportedLngs`
* matching still applies (e.g. `fr-FR` -> `fr`, `ja` -> `ja`).
*/
export function convertDetectedLanguage(value: string): string {
const lower = value.trim().replaceAll('_', '-').toLowerCase()
if (!lower.startsWith('zh')) return value
if (
lower === 'zh-tw' ||
lower === 'zh-hk' ||
lower === 'zh-mo' ||
lower.startsWith('zh-hant')
) {
return 'zhTW'
}
return 'zhCN'
}
/**
* Convert an interface language code (the values i18next uses, such as `zhCN` /
* `zhTW`) into a valid BCP-47 locale tag that the `Intl.*` APIs accept.
*
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or sign in to comment