跳转至

国际化(i18n)

控制台经 next-intl v4 支持英文en)与中文zh)。URL 不含语言前缀(localePrefix: "never")。


配置

路由(i18n/routing.ts

export const routing = defineRouting({
  locales: ["zh", "en"],
  defaultLocale: "zh",
  localePrefix: "never",
});

语言由中间件 / proxy.ts 从 cookie 或 Accept-Language 解析。

请求配置(i18n/request.ts

请求时加载文案:

  1. readFileSync 读取 messages/${locale}.json(避免 Turbopack 动态 import 挂起)
  2. deepMerge 合并所有 messages/fragments/*.${locale}.json
  3. NextIntlClientProvider 返回 { locale, messages }

文案文件布局

frontend/messages/
├── en.json              # Shared / shell strings
├── zh.json
└── fragments/
    ├── qa.en.json       # namespace: "qa"
    ├── qa.zh.json
    ├── ingest.en.json
    ├── kb.en.json
    ├── health.en.json
    └── …

Fragment 约定

每个 fragment 文件在顶层命名空间:

{
  "qa": {
    "composer": {
      "placeholder": "Ask anything…"
    },
    "error": {
      "query": "Query failed"
    }
  }
}

deepMerge 递归已有 key —— fragment 扩展基础文案而不覆盖兄弟节点。

新增页面命名空间

  1. 创建 messages/fragments/mypage.en.json + .zh.json
  2. 无需改 request.ts —— 后缀扫描自动发现
  3. 组件中使用 useTranslations("mypage")

组件中的用法

Client 组件

import { useTranslations } from "next-intl";

function Composer() {
  const t = useTranslations("qa");
  return <span>{t("composer.placeholder")}</span>;
}

嵌套命名空间

const t = useTranslations("qa.sources");
const tRail = useTranslations("qa.rail");

Server 组件

import { getTranslations } from "next-intl/server";

const t = await getTranslations("kb");

App Router 中的语言

app/[locale]/layout.tsx

  • generateStaticParams() → 预渲染两种语言
  • layout 中 setRequestLocale(locale) 以静态优化
  • 无效 locale → notFound()

<html lang={locale}> 用于无障碍与 SEO。


Fragment 清单(问答示例)

messages/fragments/qa.en.json 覆盖:

命名空间段 UI 区域
qa.composer 提示、模式、附件
qa.sources 证据栏
qa.rail 结构 / 预览标签
qa.history 会话抽屉
qa.scope Scope 过滤抽屉
qa.error Toast 文案

并行 qa.zh.json 须保持 key 一致 —— 开发环境缺 key 时回退为 key 路径。


日期 / 数字格式化

展示与语言相关的值时用 next-intl formatter:

import { useFormatter } from "next-intl";
const format = useFormatter();
format.dateTime(new Date(session.updated_at));

历史分组(history-utils.ts)用 UTC 日历计算 —— UI 标签来自 qa.history.* key。


API 内容语言

后端 LLM 答案遵循模型默认(可能中英混杂)。UI 字符串完全本地化;引用内容来自语料语言,非 UI locale。


测试语言

切换语言途径:

  • 用户偏好 store(prefsStore,若已接线)
  • 中间件设置的 cookie
  • 首次访问时浏览器 Accept-Language

相关文档