Next.jsnext-intli18n

为什么在 next-intl 中使用 getI18n 加载对象而不是 JSON 文件

使用 next-intl 做国际化时,我们选择了用对象结构管理语言内容而不是纯 JSON 文件,尤其是在处理列表类结构(如问答、服务列表)时,能带来更好的开发体验和可维护性。

RaytonX
1 min read

在使用 next-intl 进行国际化开发时,官方文档推荐将翻译内容保存在 JSON 文件中,例如:

// messages/en.json
{
  "faq.q1": "What is your service?",
  "faq.a1": "We provide..."
}

但在实际开发中,我们团队逐步转向了使用 TypeScript 对象的方式进行组织,通过 getI18n(locale) 动态加载结构化的内容对象:

// i18n/en.ts
export const en = {
  faq: {
    items: [
      { question: "What is your service?", answer: "We provide..." },
      ...
    ]
  }
}

为什么选择对象结构而不是 JSON?

1. 更适合结构化内容(如 FAQ、服务列表)

当你需要展示一个列表(如 FAQ 问答、功能模块等)时,若使用 JSON,需要用 q1、a1、q2、a2 等方式硬编码。如果新增一项,意味着:

  • 必须同时修改中英文多个 JSON 文件
  • 还要修改 React 组件的 key 映射逻辑

而使用对象数组,只需添加一个新项即可,无需更改组件逻辑。

2. 更好的开发体验

使用 TypeScript 的对象结构,开发者可以:

  • 获得更强的类型提示和自动补全
  • 避免 key 拼写错误
  • 更清晰地管理内容结构

3. 更易维护与扩展

随着项目增长,JSON 文件会变得臃肿难以维护。而对象结构可以:

  • 通过模块化按页面或功能分割内容(如 faq.ts、services.ts)
  • 更方便团队协作与版本管理

4. 与组件逻辑更解耦

组件只需遍历结构化内容即可,无需手动拼 key:

{t.faq.items.map((item, index) => (
  <FaqItem key={index} question={item.question} answer={item.answer} />
))}

比起逐个写 t('faq.q1'), t('faq.a1') 更清晰、易维护。

结语

虽然 JSON 是国际化的主流格式,但在实际工程中,对于结构化和频繁变动的内容,使用对象形式组织语言内容并通过 getI18n(locale) 动态加载,是更现代、更可维护的实践。

这种方式特别适用于构建复杂前端页面、动态列表和 B2B SaaS 系统,能显著降低维护成本、提高开发效率。