# General Translation Knowledge Base: react-intl 替代方案：General Translation 与 react-intl 对比
URL: https://generaltranslation.com/zh/kb/general-translation-vs-react-intl.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: General Translation 让 React 团队在保留 ICU 消息语法的同时，获得译文生成、共享术语和仪表板审校能力。react-intl 提供格式化功能和 FormatJS 目录工具；General Translation 还能直接生成译文。
Category: 国际化
Last updated: 2026-10-16
Authors: Kevin Wu, Jackie Chen
Published: 2026-10-16

react-intl 是 [FormatJS 推出的 React 库](https://formatjs.github.io/docs/react-intl)。使用时，你需要用 ICU MessageFormat 将每条消息以 `defaultMessage` 的形式内联编写，并为译者添加 `description`；然后通过 `formatjs extract` 将所有消息提取到一个 JSON 目录中，最后借助 `IntlProvider` 渲染翻译后的消息目录。它本身并不负责翻译：提取出的目录需要由你自己、你的译者或翻译管理系统 (TMS) 来处理，拿回翻译后的文件后再进行编译。General Translation 的库同样能渲染 ICU 消息，而且 General Translation 还会直接生成译文。

## react-intl 的优势

* **全面采用 ICU MessageFormat。** [支持使用 `#` 的复数形式、`=0` 等精确匹配，以及 `select` 和 `selectordinal`](https://formatjs.github.io/docs/core-concepts/icu-syntax)，底层基于浏览器的 `Intl` API。
* **内联源文本。** FormatJS [建议以内联方式编写 `defaultMessage` 和 `description`](https://formatjs.github.io/docs/getting-started/message-declaration)，再由 `babel-plugin-formatjs` 或 `@swc/plugin-formatjs` 自动生成消息 ID，无需人工定义键。
* **面向 TMS 工作流的工具链。** [`formatjs extract`](https://formatjs.github.io/docs/tooling/cli) 负责生成目录，内置格式化器可输出适用于 Crowdin、Lokalise、Smartling 和 Transifex 的文件，`formatjs compile` 用于预解析消息，`formatjs verify` 则检查消息目录中是否有缺失或多余的键。
* **TypeScript。** [第 12 版可以为每条消息的 ICU 参数提供类型](https://formatjs.github.io/docs/react-intl/upgrade-guide-12.x)。
* **持续维护。** [第 12 版于 2026 年 9 月发布](https://github.com/formatjs/formatjs/blob/main/packages/react-intl/CHANGELOG.md)，采用 BSD-3-Clause 许可证。

## react-intl 需要你自己处理的部分

下面是一个用 react-intl 实现的简单收件箱。英文文案以 `defaultMessage` 的形式保留在组件中：

```jsx title="Inbox.jsx"
import { FormattedMessage } from 'react-intl';

export function Inbox({ count }) {
  return (
    <section>
      <h1>
        <FormattedMessage defaultMessage="Inbox" description="Heading of the inbox page" />
      </h1>
      <p>
        <FormattedMessage
          defaultMessage="You have {count, plural, one {# unread message} other {# unread messages}}."
          description="Number of unread messages in the inbox"
          values={{ count }}
        />
      </p>
    </section>
  );
}
```

`formatjs extract` 会将这些消息提取为一个目录，并以自动生成的 ID 作为键：

```json title="lang/en.json"
{
  "U5vJOY": {
    "defaultMessage": "You have {count, plural, one {# unread message} other {# unread messages}}.",
    "description": "Number of unread messages in the inbox"
  },
  "gBGgGs": {
    "defaultMessage": "Inbox",
    "description": "Heading of the inbox page"
  }
}
```

每种目标语言都需要一份已翻译的消息，且其中的 ICU 语法须保持完整。`IntlProvider` 既接受消息字符串，也接受预编译消息；后者可通过 `formatjs compile` 生成。提取出的描述符包含每条消息及其描述。若要使用本示例中自动生成的 ID，请在构建流程中配置 Babel 或 SWC 插件。在 [Next.js App Router](https://formatjs.github.io/docs/guides/nextjs-app-router) 中，react-intl 的组件运行于客户端组件内，而服务端代码则通过 `react-intl/server` 提供的 `createIntl` 来格式化消息。

## 保留 ICU 消息并生成译文

General Translation 的库与 react-intl 作用相同：渲染 ICU 消息、应用各区域设置的复数规则，并格式化数字、货币和日期。由于 [`useGT`](/docs/react/reference/hooks/use-gt) 支持相同的语法，你的 ICU 字符串几乎无需改动即可迁移：

```tsx title="Inbox.tsx"
import { useGT } from 'gt-react';

export function Inbox({ count }: { count: number }) {
  const gt = useGT();
  return (
    <section>
      <h1>{gt('Inbox', { $context: 'Heading of the inbox page' })}</h1>
      <p>
        {gt('You have {count, plural, one {# unread message} other {# unread messages}}.', {
          count,
          $context: 'Number of unread messages in the inbox',
        })}
      </p>
    </section>
  );
}
```

[`npx gt translate`](/docs/cli/reference/commands/translate) 只需一条命令，即可提取这些字符串、结合其上下文备注生成译文，并写入目标消息目录。本示例将两条 FormatJS 描述都保留为 `$context`。共享的[词汇表术语和自定义提示词](/docs/platform/dashboard/guides/defining-context-for-translations)可用于统一术语和语气，审校人员则可在[仪表板](/docs/platform/dashboard/guides/reviewing-translations)中编辑翻译结果。

`#` 会根据各区域设置进行格式化，因此数值 12345 在英语中显示为 &quot;12,345&quot;，在西班牙语中显示为 &quot;12.345&quot;。对于包含标记的 JSX，[`<T>`](/docs/react/reference/components/t) 会翻译整个标记块，其中的元素也一并处理。在 `gt-next` 中，它可直接用于服务端组件。

Ramp 的仪表板、落地页和 iOS 应用借助 General Translation 支持 11 种以上的区域设置。 (参见[生产环境部署](https://generaltranslation.com/enterprise)。)

## react-intl 与 General Translation 速览

| 功能                 | react-intl                                                                                    | General Translation                                                                                                  |
| ------------------ | --------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------- |
| 文案编写方式             | 以 ICU 格式内联编写 `defaultMessage`，再提取到 JSON 目录中                                                   | 在 [`<T>`](/docs/react/reference/components/t) 中内联编写 JSX，或在 [`useGT`](/docs/react/reference/hooks/use-gt) 中使用 ICU 字符串 |
| 是否翻译你的内容           | 否                                                                                             | 是，通过 [`npx gt translate`](/docs/cli/reference/commands/translate)                                                    |
| 目录工作流              | 提取消息，通过你选择的工作流翻译，可选择预编译；由插件生成 ID                                                              | [`npx gt translate`](/docs/cli/reference/commands/translate) 在构建前完成提取和翻译                                             |
| 翻译上下文              | 消息本身及其描述                                                                                      | 带 `$context` 的 ICU 字符串；带内联组件标记的 JSX 结构；共享的词汇表和自定义提示词                                                                 |
| Next.js App Router | 在客户端组件中使用组件；在服务端使用 `createIntl`                                                               | 在服务端组件和客户端组件中均可使用 [`<T>`](/docs/react/reference/components/t)                                                        |
| 许可证                | [BSD-3-Clause](https://github.com/formatjs/formatjs/blob/main/packages/react-intl/LICENSE.md) | JavaScript 库和 CLI 均采用 MIT 许可证                                                                                        |

如果你的 ICU 消息目录和 TMS 格式化工具已运行良好，或者你依赖其类型化消息参数或 `formatjs verify`，又或者你需要在 React 之外使用 FormatJS，那么继续使用 react-intl 即可。如果你希望沿用 ICU 编写方式，同时将翻译生成和审校纳入开发工作流，那么 General Translation 是更好的选择。

## 从 react-intl 迁移

每次只迁移一个组件或路由。将每个 `<FormattedMessage>` 替换为 [`useGT`](/docs/react/reference/hooks/use-gt) 调用，保留原有的 ICU 字符串，并将其描述作为 `$context` 传入，如上文所示。对于富 JSX 内容，请使用 [`<T context="…">`](/docs/react/reference/components/t#context)。尚未迁移的组件仍继续加载现有的 react-intl 消息目录。待最后一个组件迁移完成后，移除 FormatJS 插件以及 extract 和 compile 脚本。 (参见[迁移国际化库](/docs/react/guides/migrating-i18n-libraries)。)

## 其他 react-intl 替代方案

准备弃用 react-intl 的团队通常还会比较以下库：

* **i18next：** 渲染基于键的消息目录并支持复数选择，搭配 react-i18next 和 next-i18next，是 React 和 Next.js 应用的常见选择。 (参见 [General Translation vs. i18next](/kb/general-translation-vs-i18next)。) 
* **Lingui：** 文案以内联方式写在代码中，并将消息编译为消息目录，运行时体积小巧。 (参见 [General Translation vs. Lingui](/kb/general-translation-vs-lingui)。) 
* **next-intl：** 在 Next.js App Router 应用中渲染目录消息，支持服务端组件。 (参见 [next-intl vs. gt-next](/kb/next-intl-vs-gt-next)。) 
* **Paraglide JS：** 将消息目录编译为带类型、支持 tree-shaking 的消息函数。 (参见 [General Translation vs. Paraglide JS](/kb/general-translation-vs-paraglide)。) 
* **Intlayer：** 将每个组件的内容存放在带类型的声明文件中，各语言内容并列放置。 (参见 [General Translation vs. Intlayer](/kb/general-translation-vs-intlayer)。)

## 要点总结

* react-intl 负责格式化 ICU 消息并提供目录工具，但翻译本身需要通过单独的工作流生成。
* General Translation 只需一条 CLI 命令即可完成提取和翻译，同时保留 description 上下文，并为审校人员提供仪表板编辑器。
* 你的 ICU 字符串几乎无需改动即可迁移到 [`useGT`](/docs/react/reference/hooks/use-gt)，并且支持逐个组件迁移。

## Related questions

- [General Translation 与 i18next、react-intl 和 next-intl 对比：应该选择哪个国际化库？](https://generaltranslation.com/zh/kb/general-translation-vs-i18n-libraries.mdx): i18next、react-intl 和 next-intl 等开源库本身并不翻译任何内容。它们只负责显示你在各语言目录文件中提供的译文，这些译文由你、你的译者或其他服务编写。General Translation 的库同样开源，承担同样的工作，此外 General Translation 还会以你的代码为上下文完成翻译。
- [i18next 替代方案：General Translation 与 i18next 对比](https://generaltranslation.com/zh/kb/general-translation-vs-i18next.mdx): 如果你希望将文案内联在 React 组件中，并借助其 JSX 结构和产品上下文生成译文，请选择 General Translation。你也可以继续使用 i18next，并用 General Translation 翻译现有的目录。i18next 负责消息渲染和复数形式选择，译文则需要由单独的服务生成。
- [General Translation 与 Lingui：该选哪一个？](https://generaltranslation.com/zh/kb/general-translation-vs-lingui.mdx): 如果你希望像使用 Lingui 一样将文案内联在代码中，同时以 JSX 结构作为上下文自动生成译文，请选择 General Translation。Lingui 会将内联消息提取到消息目录中，交由译者或已连接的服务翻译。General Translation 的 CLI 会随代码变更自动更新译文，你的团队可以在仪表板中审阅。
- [General Translation 与 vue-i18n 对比：该选哪一个？](https://generaltranslation.com/zh/kb/general-translation-vs-vue-i18n.mdx): General Translation 让 Vue 团队可以直接在模板中编写源文案，并通过 CLI 生成译文。其 gt-vue 插件在渲染这些内容时，会应用符合区域设置的复数形式和数字格式化。如果你希望免去维护基于键的源文件，可以选择它；而对于使用 Nuxt i18n 模块、已有成熟目录工作流的团队，vue-i18n 依然是合适的选择。
- [如何在 React 中处理复数形式？](https://generaltranslation.com/zh/kb/how-to-handle-plurals-in-react.mdx): 不要用 n === 1 这类判断硬编码复数逻辑。如果应用只支持英语，一个简单的辅助函数就够用了；但多语言应用需要符合区域设置的复数规则，而 gt-react 或 gt-next 中的 `<Plural>` 等 i18n 组件能够为每种语言处理这些规则。

## Previous and next questions

- Previous question: [React 应用最适合使用哪个国际化库？](https://generaltranslation.com/zh/kb/best-react-i18n-library.mdx)
- Next question: [Smartling 替代方案：General Translation 与 Smartling 对比](https://generaltranslation.com/zh/kb/general-translation-vs-smartling.mdx)

## Sitemap

See the [Knowledge Base sitemap](https://generaltranslation.com/zh/kb/sitemap.md) for every article.
