You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 

5.6 KiB

国际化(i18n)

文档版本:v1.1
最后更新:2025-01-18


目录

  1. 技术方案
  2. i18n 配置
  3. 语言文件结构
  4. 使用方式
  5. 语言切换

1. 技术方案

使用 react-i18next 实现多语言支持。

npm install react-i18next i18next i18next-browser-languagedetector i18next-http-backend

2. i18n 配置

// src/lib/i18n.ts
import i18n from "i18next";
import { initReactI18next } from "react-i18next";
import LanguageDetector from "i18next-browser-languagedetector";
import Backend from "i18next-http-backend";

i18n
  .use(Backend)
  .use(LanguageDetector)
  .use(initReactI18next)
  .init({
    // 支持的语言
    supportedLngs: ["zh-CN", "en-US", "zh-TW"],
    // 默认语言
    fallbackLng: "zh-CN",
    // 默认命名空间
    defaultNS: "common",
    // 命名空间列表
    ns: ["common", "editor", "settings", "errors"],
    // 语言检测配置
    detection: {
      order: ["localStorage", "navigator"],
      caches: ["localStorage"],
      lookupLocalStorage: "i18nextLng",
    },
    // 后端配置
    backend: {
      loadPath: "/locales/{{lng}}/{{ns}}.json",
    },
    // React 配置
    react: {
      useSuspense: true,
    },
    // 插值配置
    interpolation: {
      escapeValue: false,
    },
  });

export default i18n;

3. 语言文件结构

public/
└── locales/
    ├── zh-CN/           # 简体中文(默认)
    │   ├── common.json
    │   ├── editor.json
    │   ├── settings.json
    │   └── errors.json
    ├── en-US/           # 英文
    │   ├── common.json
    │   ├── editor.json
    │   ├── settings.json
    │   └── errors.json
    └── zh-TW/           # 繁体中文
        ├── common.json
        ├── editor.json
        ├── settings.json
        └── errors.json

3.1 语言文件示例

// public/locales/zh-CN/common.json
{
  "app": {
    "name": "Jointo",
    "tagline": "AI 驱动的视频制作平台"
  },
  "nav": {
    "home": "首页",
    "projects": "项目",
    "settings": "设置",
    "help": "帮助"
  },
  "actions": {
    "save": "保存",
    "cancel": "取消",
    "delete": "删除",
    "edit": "编辑",
    "create": "创建",
    "export": "导出",
    "import": "导入"
  },
  "messages": {
    "saveSuccess": "保存成功",
    "saveFailed": "保存失败",
    "confirmDelete": "确定要删除吗?"
  }
}
// public/locales/en-US/common.json
{
  "app": {
    "name": "Jointo",
    "tagline": "AI-Powered Video Production Platform"
  },
  "nav": {
    "home": "Home",
    "projects": "Projects",
    "settings": "Settings",
    "help": "Help"
  },
  "actions": {
    "save": "Save",
    "cancel": "Cancel",
    "delete": "Delete",
    "edit": "Edit",
    "create": "Create",
    "export": "Export",
    "import": "Import"
  },
  "messages": {
    "saveSuccess": "Saved successfully",
    "saveFailed": "Failed to save",
    "confirmDelete": "Are you sure you want to delete?"
  }
}

4. 使用方式

4.1 基础使用

import { useTranslation } from "react-i18next";

function MyComponent() {
  const { t } = useTranslation();

  return (
    <div>
      <h1>{t("app.name")}</h1>
      <button>{t("actions.save")}</button>
    </div>
  );
}

4.2 使用多个命名空间

function EditorComponent() {
  const { t } = useTranslation(["editor", "common"]);

  return (
    <div>
      <h1>{t("editor:title")}</h1>
      <button>{t("common:actions.save")}</button>
    </div>
  );
}

4.3 带参数的翻译

// JSON: "welcome": "欢迎, {{name}}!"
<p>{t("welcome", { name: "John" })}</p>

4.4 复数处理

// JSON: "items": "{{count}} 个项目", "items_plural": "{{count}} 个项目"
<p>{t("items", { count: 5 })}</p>

5. 语言切换

5.1 Settings Store

// src/stores/settingsStore.ts
import { create } from "zustand";
import { persist } from "zustand/middleware";
import i18n from "@/lib/i18n";

type Language = "zh-CN" | "en-US" | "zh-TW";

interface SettingsState {
  language: Language;
  setLanguage: (lang: Language) => void;
}

export const useSettingsStore = create<SettingsState>()(
  persist(
    (set) => ({
      language: "zh-CN",
      setLanguage: (lang) => {
        i18n.changeLanguage(lang);
        set({ language: lang });
      },
    }),
    {
      name: "settings-store",
    },
  ),
);

5.2 语言选择器组件

// src/components/common/LanguageSelector.tsx
import { useSettingsStore } from "@stores/settingsStore";
import {
  Select,
  SelectContent,
  SelectItem,
  SelectTrigger,
  SelectValue,
} from "@/components/ui/select";

const languages = [
  { value: "zh-CN", label: "简体中文" },
  { value: "en-US", label: "English" },
  { value: "zh-TW", label: "繁體中文" },
];

export function LanguageSelector() {
  const { language, setLanguage } = useSettingsStore();

  return (
    <Select value={language} onValueChange={setLanguage}>
      <SelectTrigger className="w-[180px]">
        <SelectValue />
      </SelectTrigger>
      <SelectContent>
        {languages.map((lang) => (
          <SelectItem key={lang.value} value={lang.value}>
            {lang.label}
          </SelectItem>
        ))}
      </SelectContent>
    </Select>
  );
}

相关文档


最后更新:2025-01-18 | 版本:v1.1