feat: 增强国际化支持与安全头配置

- 在 .env.example 中新增 i18next 相关配置项以支持多语言功能
- 在 next.config.ts 中添加安全头配置以支持 iframe 嵌入
- 更新 Providers 组件以引入 i18n 配置
- 在 PlayerAppShell 中集成 LanguageSwitcher 组件以实现语言切换功能
- 优化 HallWalletStrip 组件的网络状态管理逻辑
- 更新多个组件以支持国际化文本
This commit is contained in:
2026-05-13 17:53:56 +08:00
parent c8f8f90515
commit 587a6ad66c
32 changed files with 2126 additions and 436 deletions

85
src/i18n/index.ts Normal file
View File

@@ -0,0 +1,85 @@
import i18n from "i18next";
import LanguageDetector from "i18next-browser-languagedetector";
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 neCommon from "./locales/ne/common.json";
import neEntry from "./locales/ne/entry.json";
import neLayout from "./locales/ne/layout.json";
import zhCommon from "./locales/zh/common.json";
import zhEntry from "./locales/zh/entry.json";
import zhLayout from "./locales/zh/layout.json";
/** 对齐后端与产品:尼泊尔语 / 英语 / 中文(简体) */
export const SUPPORTED_LANGUAGES = [
{ code: "en" as const, flag: "🇺🇸" },
{ code: "ne" as const, flag: "🇳🇵" },
{ code: "zh" as const, flag: "🇨🇳" },
];
export type AppLanguage = (typeof SUPPORTED_LANGUAGES)[number]["code"];
export const DEFAULT_LANGUAGE: AppLanguage = "en";
const namespaces = ["common", "entry", "layout"] as const;
const resources = {
en: {
common: enCommon,
entry: enEntry,
layout: enLayout,
},
ne: {
common: neCommon,
entry: neEntry,
layout: neLayout,
},
zh: {
common: zhCommon,
entry: zhEntry,
layout: zhLayout,
},
} satisfies Record<
AppLanguage,
Record<(typeof namespaces)[number], Record<string, unknown>>
>;
export function normalizeLanguage(lang: string | undefined): AppLanguage {
const base = lang?.split("-")[0]?.toLowerCase();
if (base === "ne") return "ne";
if (base === "zh") return "zh";
return "en";
}
if (!i18n.isInitialized) {
void i18n
.use(LanguageDetector)
.use(initReactI18next)
.init({
resources,
fallbackLng: DEFAULT_LANGUAGE,
supportedLngs: ["en", "ne", "zh"],
defaultNS: "common",
ns: [...namespaces],
/** zh-CN → zhne-NP → ne未匹配时用 fallbackLng */
load: "languageOnly",
detection: {
order: ["localStorage", "navigator"],
caches: ["localStorage"],
lookupLocalStorage: "i18nextLng",
},
interpolation: {
escapeValue: false,
},
react: {
useSuspense: false,
},
});
}
export default i18n;