Commit becc18e3 by CaIon

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

parent 8f31b305
...@@ -20,6 +20,7 @@ import i18n from 'i18next' ...@@ -20,6 +20,7 @@ import i18n from 'i18next'
import LanguageDetector from 'i18next-browser-languagedetector' import LanguageDetector from 'i18next-browser-languagedetector'
import { initReactI18next } from 'react-i18next' import { initReactI18next } from 'react-i18next'
import { convertDetectedLanguage } from './languages'
import en from './locales/en.json' import en from './locales/en.json'
import fr from './locales/fr.json' import fr from './locales/fr.json'
import ja from './locales/ja.json' import ja from './locales/ja.json'
...@@ -44,8 +45,8 @@ i18n ...@@ -44,8 +45,8 @@ i18n
.init({ .init({
resources, resources,
fallbackLng: 'en', fallbackLng: 'en',
supportedLngs: ['en', 'zhCN', 'fr', 'ru', 'ja', 'vi','zhTW'], supportedLngs: ['en', 'zhCN', 'fr', 'ru', 'ja', 'vi', 'zhTW'],
load: 'currentOnly', // Convert zh-CN -> zh load: 'currentOnly',
nsSeparator: false, // Allow literal colons in keys (e.g., URLs, labels) nsSeparator: false, // Allow literal colons in keys (e.g., URLs, labels)
debug: import.meta.env.DEV, debug: import.meta.env.DEV,
interpolation: { interpolation: {
...@@ -54,6 +55,9 @@ i18n ...@@ -54,6 +55,9 @@ i18n
detection: { detection: {
order: ['localStorage', 'navigator'], order: ['localStorage', 'navigator'],
caches: ['localStorage'], 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 = ...@@ -33,7 +33,7 @@ export type InterfaceLanguageCode =
export function normalizeInterfaceLanguage(value?: string | null): string { export function normalizeInterfaceLanguage(value?: string | null): string {
if (!value) return 'en' 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') { if (value === 'zh-TW' || value === 'zh-HK' || value === 'zh-MO' || value === 'zhTW') {
normalized = 'zhTW' normalized = 'zhTW'
} }
...@@ -47,6 +47,30 @@ export function normalizeInterfaceLanguage(value?: string | null): string { ...@@ -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` / * 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. * `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