refactor: 完成全站国际化改造,统一多语言支持

此提交完成了全项目的国际化适配:
1. 新增多语言翻译文件与基础配置
2. 替换所有硬编码文本为i18n调用
3. 优化语言切换与文档语言同步逻辑
4. 重构部分业务逻辑以支持动态翻译
5. 移除过时代码与硬编码配置
This commit is contained in:
2026-05-15 10:41:14 +08:00
parent ac612cb32c
commit f2c7f5e4f1
53 changed files with 2179 additions and 767 deletions

View File

@@ -1,3 +1,5 @@
"use client";
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import { initReactI18next } from "react-i18next";
@@ -5,12 +7,15 @@ import { initReactI18next } from "react-i18next";
import enCommon from "./locales/en/common.json";
import enEntry from "./locales/en/entry.json";
import enLayout from "./locales/en/layout.json";
import enPlayer from "./locales/en/player.json";
import neCommon from "./locales/ne/common.json";
import neEntry from "./locales/ne/entry.json";
import neLayout from "./locales/ne/layout.json";
import nePlayer from "./locales/ne/player.json";
import zhCommon from "./locales/zh/common.json";
import zhEntry from "./locales/zh/entry.json";
import zhLayout from "./locales/zh/layout.json";
import zhPlayer from "./locales/zh/player.json";
/** 对齐后端与产品:尼泊尔语 / 英语 / 中文(简体) */
export const SUPPORTED_LANGUAGES = [
@@ -23,23 +28,26 @@ export type AppLanguage = (typeof SUPPORTED_LANGUAGES)[number]["code"];
export const DEFAULT_LANGUAGE: AppLanguage = "en";
const namespaces = ["common", "entry", "layout"] as const;
const namespaces = ["common", "entry", "layout", "player"] as const;
const resources = {
en: {
common: enCommon,
entry: enEntry,
layout: enLayout,
player: enPlayer,
},
ne: {
common: neCommon,
entry: neEntry,
layout: neLayout,
player: nePlayer,
},
zh: {
common: zhCommon,
entry: zhEntry,
layout: zhLayout,
player: zhPlayer,
},
} satisfies Record<
AppLanguage,
@@ -53,6 +61,12 @@ export function normalizeLanguage(lang: string | undefined): AppLanguage {
return "en";
}
export function syncDocumentLanguage(lang: AppLanguage): void {
if (typeof document === "undefined") return;
document.documentElement.lang = lang;
}
if (!i18n.isInitialized) {
void i18n
.use(LanguageDetector)
@@ -80,6 +94,12 @@ if (!i18n.isInitialized) {
useSuspense: false,
},
});
syncDocumentLanguage(normalizeLanguage(i18n.resolvedLanguage ?? i18n.language));
i18n.on("languageChanged", (lang) => {
syncDocumentLanguage(normalizeLanguage(lang));
});
}
export default i18n;