feat(i18n): add Traditional Chinese (Taiwan) locale

Add zh-TW as a new supported language, covering all 1500+ translation keys
with Taiwan-standard terminology and phrasing.

Changes:
- src/i18n/locales/zh-TW.json: new file, full Traditional Chinese translation
- src/i18n/index.ts: import and register zh-TW locale
- src/types/common.ts: add 'zh-TW' to Language union type
- src/utils/constants.ts: add zh-TW to LANGUAGE_ORDER and LANGUAGE_LABEL_KEYS
- src/utils/language.ts: add zh-tw/zh-hant browser locale detection
- src/i18n/locales/*.json: add chinese_tw label key to all locales

Co-authored-by: lmanchu <lman.chu@gmail.com>
This commit is contained in:
lmanchu
2026-04-12 14:15:46 +08:00
Unverified
parent 5cbfbe8fea
commit 30f14500c8
8 changed files with 1522 additions and 2 deletions
+2
View File
@@ -5,6 +5,7 @@
import i18n from 'i18next';
import { initReactI18next } from 'react-i18next';
import zhCN from './locales/zh-CN.json';
import zhTW from './locales/zh-TW.json';
import en from './locales/en.json';
import ru from './locales/ru.json';
import { getInitialLanguage } from '@/utils/language';
@@ -12,6 +13,7 @@ import { getInitialLanguage } from '@/utils/language';
i18n.use(initReactI18next).init({
resources: {
'zh-CN': { translation: zhCN },
'zh-TW': { translation: zhTW },
en: { translation: en },
ru: { translation: ru }
},
+1
View File
@@ -1487,6 +1487,7 @@
"language": {
"switch": "Language",
"chinese": "中文",
"chinese_tw": "Traditional Chinese (Taiwan)",
"english": "English",
"russian": "Русский"
},
+1
View File
@@ -1486,6 +1486,7 @@
"language": {
"switch": "Язык",
"chinese": "中文",
"chinese_tw": "繁體中文(台灣)",
"english": "English",
"russian": "Русский"
},
+1
View File
@@ -1487,6 +1487,7 @@
"language": {
"switch": "语言",
"chinese": "中文",
"chinese_tw": "繁體中文(台灣)",
"english": "English",
"russian": "Русский"
},
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -4,7 +4,7 @@
export type Theme = 'light' | 'white' | 'dark' | 'auto';
export type Language = 'zh-CN' | 'en' | 'ru';
export type Language = 'zh-CN' | 'zh-TW' | 'en' | 'ru';
export type NotificationType = 'info' | 'success' | 'warning' | 'error';
+2 -1
View File
@@ -40,9 +40,10 @@ export const STORAGE_KEY_SIDEBAR = 'cli-proxy-sidebar-collapsed';
export const STORAGE_KEY_AUTH_FILES_PAGE_SIZE = 'cli-proxy-auth-files-page-size';
// 语言配置
export const LANGUAGE_ORDER = defineLanguageOrder(['zh-CN', 'en', 'ru'] as const);
export const LANGUAGE_ORDER = defineLanguageOrder(['zh-CN', 'zh-TW', 'en', 'ru'] as const);
export const LANGUAGE_LABEL_KEYS: Record<Language, string> = {
'zh-CN': 'language.chinese',
'zh-TW': 'language.chinese_tw',
en: 'language.english',
ru: 'language.russian'
};
+1
View File
@@ -40,6 +40,7 @@ const getBrowserLanguage = (): Language => {
}
const raw = navigator.languages?.[0] || navigator.language || 'zh-CN';
const lower = raw.toLowerCase();
if (lower.startsWith('zh-tw') || lower.startsWith('zh-hant')) return 'zh-TW';
if (lower.startsWith('zh')) return 'zh-CN';
if (lower.startsWith('ru')) return 'ru';
return 'en';