# General Translation Knowledge Base: 如何从 Crowdin 迁移到 General Translation？
URL: https://generaltranslation.com/zh/kb/migrate-from-crowdin.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: 保留现有的资源文件、国际化库和已审校的译文。开启 Skip untranslated strings，下载译文，停止 Crowdin 的 Git 集成推送译文，并在首次运行 npx gt translate 之前，使用 npx gt upload 导入这些文件。之后，General Translation 会在构建过程中翻译新增和变更的字符串，并使用 上下文分组 中的词汇表。
Category: 工作流工具
Last updated: 2026-11-12
Authors: Kevin Wu
Published: 2026-11-12

Crowdin 中保存着你的源文件及其译文、词汇表和翻译记忆库，其 Git 集成会以拉取请求的形式回传译文。迁移到 General Translation 时，应用现有读取的资源文件可以继续沿用：`gt` CLI 会将这些文件连同已有译文一并导入，之后在构建或 CI 中翻译新增和变更的字符串。你的国际化库、键和文件布局都无需改动；将文案改为内联是一个独立的可选步骤 (参见[从 react-i18next 迁移](/kb/migrate-from-react-i18next)或[从 next-intl 迁移](/kb/migrate-from-next-intl)) 。你的词汇表会转为一个 上下文分组，可在应用、文档和其他项目之间共享。

## 哪些内容可以从 Crowdin 迁移过来？

| 在 Crowdin 中                           | 在 General Translation 中                                                                                                     |
| ------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
| `crowdin.yml` 中的 `files` 条目           | `gt.config.json` 中的 `files`，用 `[locale]` 替代 `%locale%`                                                                      |
| 翻译后的文件                                | 通过 [`npx gt upload`](/docs/cli/reference/commands/upload) 导入，在对应源内容变更之前会一直保留                                                |
| 词汇表                                   | [上下文分组](/docs/platform/dashboard/guides/defining-context-for-translations)中的词汇表，可从 CSV 导入                                   |
| 风格指南和 AI 提示词                          | [自定义提示词](/docs/platform/dashboard/guides/defining-context-for-translations)，可全局设置，也可按区域设置分别设置                               |
| 字符串上下文和最大长度                           | Android 和 iOS 源文件中的注释 (General Translation 会将其作为上下文读取) ；JSON 和 YAML 则使用[键级元数据](/docs/cli/reference/keyed-metadata)文件        |
| 翻译记忆库                                 | 你上传的译文：未更改的字符串沿用已有译文，只翻译新增和更改的字符串。不支持导入 TMX 文件                                                                              |
| GitHub 或 GitLab 集成 (默认使用 `l10n_` 分支)  | 在 CI 中运行 [`npx gt translate`](/docs/cli/reference/commands/translate)，或使用 [Locadex](/docs/platform/locadex/quickstart) 拉取请求 |
| 校对和批准                                 | 在[仪表板](/docs/platform/dashboard/guides/reviewing-translations)中编辑，Enterprise 方案还支持批准功能                                      |
| 移动应用的空中下载 (OTA) 内容投递                  | 译文打包在资源文件中，随每次应用发布一同交付                                                                                                      |

CLI 可读取 JSON、YAML、`.pot` 和 `.po`、iOS `.strings`、`.stringsdict` 和 `.xcstrings`、Android `strings.xml`、`.resx`、HTML、Markdown 和 MDX 等格式。 (参见[支持的格式](/docs/cli/reference/config#files)。) 不支持读取 XLIFF、ARB、Java `.properties`，以及 CSV 和 XLSX 字符串文件。

## 第 1 步：阻止 Crowdin 用源文本填充空缺

默认情况下，Crowdin 会[将未翻译的字符串导出为源文本](https://support.crowdin.com/project-settings/export/)，确保文件始终不为空。如果原样导入，这些英文内容会被当作已完成的译文。因此在下载之前，请在 Crowdin 项目的 **Settings &gt; Export** 中开启 **Skip untranslated strings** (若 **Skip untranslated files** 已开启，此选项不会生效) ，或在 `crowdin.yml` 中设置 [`skip_untranslated_strings`](https://crowdin.github.io/crowdin-cli/advanced)：

```yaml title="crowdin.yml"
files:
  - source: /locales/en/**/*.json
    translation: /locales/%locale%/**/%original_file_name%
    skip_untranslated_strings: true
```

&quot;跳过&quot;的具体含义取决于文件格式。对于扁平 JSON、YAML、Android XML、iOS `.strings` 和 `.stringsdict` 以及 `.resx`，Crowdin 会直接移除未翻译的字符串；而对于嵌套 JSON、i18next JSON、gettext PO 以及 TS 或 JS 文件，Crowdin 会将其导出为空值。因此，导入前请在这些文件中查找空字符串并将其删除。如果只想迁移已校对的译文，请添加 `export_only_approved: true`。

## 第 2 步：下载译文

如果源文件已在你的代码仓库中，请使用 [Crowdin CLI](https://crowdin.github.io/crowdin-cli/commands/crowdin-download) 下载译文。请先预览路径：

```bash
crowdin download --dryrun
crowdin download --skip-untranslated-strings
```

如果不使用 CLI，可以在 Crowdin 项目中使用 **Translations &gt; Build &amp; Download**，该操作会遵循项目的导出设置。Crowdin Enterprise 用户需要在 `crowdin.yml` 中将 `base_url` 设置为所在组织的 API 地址。

请检查区域设置文件夹的名称。`%locale%` 生成的是包含语言和地区的代码，例如 `uk-UA`；`%two_letters_code%` 则只生成语言代码，例如 `uk`。请在 `gt.config.json` 中列出相同的代码，或在导出时通过 Crowdin 的 [`languages_mapping`](https://support.crowdin.com/developer/configuration-file/) 选项重命名。

## 第 3 步：阻止 Crowdin 推送译文

Crowdin 的 GitHub 和 GitLab 集成[默认每小时同步一次](https://support.crowdin.com/github-integration/)，并从 `l10n_` 分支发起拉取请求 (GitLab 上称为合并请求) 。在 General Translation 写入任何文件之前，请清空该集成的 **Sync Schedule** 并保存，让 Crowdin 不再向你的代码仓库发送译文；注意，只有当初设置该集成的成员才能修改此项。然后关闭所有尚未处理的 `l10n_` 拉取请求，并从 CI 中移除 Crowdin 相关步骤。待 General Translation 接管这些文件后，即可彻底移除该集成。如果两个工具同时写入相同的文件，最终内容以最后写入者为准。

## 第 4 步：将 CLI 指向相同的文件

安装 `gt` CLI，并将 `crowdin.yml` 中的条目改写到 `gt.config.json` 中。每个 `translation` 模式都对应一个带有 `[locale]` 的 `include` 模式：

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["de-DE", "pt-BR", "uk-UA"],
  "files": {
    "json": { "include": ["locales/[locale]/**/*.json"] }
  }
}
```

使用 [`npx gt login`](/docs/cli/reference/commands/login) 登录并设置 `GT_PROJECT_ID`，或在配置中设置 `projectId`。在 CI 中，请将 `GT_API_KEY` 设为项目 API 密钥，该密钥需具备 **文件 &gt; 写入**、**翻译队列 &gt; 已启用** 和 **上下文 &gt; 写入** 权限。

## 第 5 步：迁移词汇表和字符串上下文

项目所有者或管理员可以在 Crowdin 的 [Glossaries](https://support.crowdin.com/glossary/) 页面将词汇表下载为 CSV 文件，也可以通过 CLI 下载 (运行 `crowdin glossary list` 可查看其 ID) ：

```bash
crowdin glossary download <glossary-id> --format csv --to ./glossary.csv
```

Crowdin 按语言命名列。将 `Term [en]` 重命名为 `term`，将 `Description [en]` 重命名为 `definition`，并将每个目标语言列 (例如 `Term [de]`) 重命名为 `translation_de`；然后删除其余列并保存文件。General Translation 的导入器可直接读取这种布局，其他布局则交由 AI 解析。在仪表板中创建一个[上下文分组](/docs/platform/dashboard/guides/defining-context-for-translations)，点击 **Import** 并选择该文件，然后在首次运行翻译之前将该分组分配给你的项目，这样新译文从一开始就会使用你的术语。

无论字符串是开发者编写的还是 Crowdin 生成的，字符串上下文都能告诉译者它的含义。Android 源文件 `strings.xml` 和 iOS 源文件 `.strings` 中每个字符串上方的注释，本身就会作为上下文传递给 General Translation。如果上下文只保存在 Crowdin 中，请通过 Crowdin 的[源字符串 API](https://support.crowdin.com/developer/api/v2/#tag/Source-Strings/operation/api.projects.strings.getMany) 获取每个字符串的 `context` 和 `maxLength`。对于 Android 和 iOS，将上下文以注释形式添加到源文件中；对于 JSON 和 YAML，则将这两项写入源文件旁的[键级元数据](/docs/cli/reference/keyed-metadata)文件：

```json title="locales/en/common.metadata.json"
{
  "checkout": {
    "save": { "context": "Button that saves the shipping address", "maxChars": 12 }
  }
}
```

将你的风格指南和 AI 提示词说明重新设置为[自定义提示词](/docs/platform/dashboard/guides/defining-context-for-translations)。如需存档翻译记忆库，可运行 `crowdin tm download <tm-id>` 将其下载为 TMX 文件。

## 第 6 步：先上传，再翻译

请先运行 [`npx gt upload`](/docs/cli/reference/commands/upload)。该命令会上传每个源文件，以及每个区域设置下对应的翻译后的文件，并将这些译文标记为已完成：

```bash
npx gt upload
npx gt translate
```

随后，[`npx gt translate`](/docs/cli/reference/commands/translate) 只会翻译缺失的内容 (例如新增的区域设置或尚无译文的文件) ，并将结果写入相同的路径。如果在 [`npx gt upload`](/docs/cli/reference/commands/upload) 之前运行 [`npx gt translate`](/docs/cli/reference/commands/translate)，生成的新译文会覆盖已下载的文件。对于 Crowdin 中尚未翻译的字符串，General Translation 会在其源文件下次变更时进行翻译。如需尽早发布这些译文，请在下载前先在 Crowdin 中完成翻译。

## 第 7 步：自动翻译新文案

今后，你可以在[构建或 CI](/kb/translations-in-ci) 流程中运行 [`npx gt translate`](/docs/cli/reference/commands/translate)，或者让 [Locadex](/docs/platform/locadex/quickstart) 自动创建包含译文的拉取请求。请将 `gt-lock.json` 提交到代码仓库：该文件记录了 CLI 已写入的译文，避免重复下载。如果你的团队会直接在代码仓库中编辑翻译后的文件，请在下次翻译前运行 [`npx gt save-local`](/docs/cli/reference/commands/save-local)，以保留这些修改。

## 什么情况下应继续使用 Crowdin？

如果你的开源项目依赖 Crowdin 的免费许可证和社区译者，需要通过其供应商市场订购人工翻译，需要交换 XLIFF 或 Office 文件，或者原生移动应用依赖 OTA (空中下载) 更新，那么建议继续使用 Crowdin。 (参见 [General Translation 与 Crowdin 对比](/kb/general-translation-vs-crowdin)。)

## 常见问题

### 我已校对的译文会丢失吗？

不会，前提是导出时跳过未翻译的字符串，并在运行 [`npx gt translate`](/docs/cli/reference/commands/translate) 之前先运行 [`npx gt upload`](/docs/cli/reference/commands/upload)。已上传的译文会一直保留，直到对应的源文本发生变化；此外，你的团队也可以在[仪表板](/docs/platform/dashboard/guides/reviewing-translations)中修正任意译文。

### 我可以继续用 Crowdin 管理部分内容吗？

可以。在 `gt.config.json` 中通过 `include` 和 `exclude` 将范围限定为由 General Translation 管理的文件，其余内容仍由 Crowdin 同步。不要让两个工具同时写入同一批文件。

## 要点总结

* 导出前请开启“Skip untranslated strings” (跳过未翻译的字符串) ，否则 Crowdin 会用源文本填补缺失的翻译，而这些源文本会被当作译文导入。
* 在 General Translation 写入相同文件之前，先停用 Crowdin 的 Git 集成，避免其推送译文。
* 在 `gt.config.json` 中复刻 `crowdin.yml` 的配置，将词汇表导入上下文分组，并在翻译前将 Crowdin 中存储的字符串上下文迁移为按键设置的上下文。
* 首次运行 [`npx gt translate`](/docs/cli/reference/commands/translate) 之前，先运行 [`npx gt upload`](/docs/cli/reference/commands/upload)；之后可在构建过程中或通过 Locadex 翻译新增文案。

## Related questions

- [Crowdin 替代方案：General Translation 与 Crowdin 对比](https://generaltranslation.com/zh/kb/general-translation-vs-crowdin.mdx): 如果你希望将文案保留在组件中，并随构建生成译文，请选择 General Translation。Crowdin 围绕资源文件、译者和审校工作流程来管理翻译项目，需要工程师将其接入应用，并随产品迭代持续维护。对于开源社区翻译和由供应商主导的翻译项目，Crowdin 依然是很好的选择。
- [如何从 Lokalise 迁移到 General Translation？](https://generaltranslation.com/zh/kb/migrate-from-lokalise.mdx): 你的资源文件、国际化库和已审校的译文都可以保留。从 Lokalise 导出时跳过空译文，关闭其 GitHub 同步，并在首次运行 npx gt translate 之前，用 npx gt upload 导入这些文件。此后，General Translation 会在构建时翻译新增和变更的字符串，你的词汇表放在上下文分组中，键描述则作为各个键的上下文。
- [如何从 Phrase 迁移到 General Translation？](https://generaltranslation.com/zh/kb/migrate-from-phrase.mdx): 保留你的区域设置文件、国际化库和已验证的译文。从 Phrase Strings 拉取文件时排除未翻译的键和后备内容，停用 Repo Sync，并在首次运行 npx gt translate 之前使用 npx gt upload 导入这些文件。此后，General Translation 会在构建过程中翻译新增和变更的字符串，你的术语库将存放在上下文分组中，键描述则作为各个键的上下文。
- [如何在每次部署时保持译文同步更新？](https://generaltranslation.com/zh/kb/translations-in-ci.mdx): 在每次生产环境构建之前，将翻译作为流水线中的一个步骤运行，这样新增文案就会在引入它的那次部署中以翻译好的形式一同上线。General Translation 的 gt CLI 通过 npx gt translate 实现这一点，所需的项目 API 密钥和项目 ID 以 CI 密钥的形式存储。
- [什么是翻译记忆库？有了 AI 还需要它吗？](https://generaltranslation.com/zh/kb/what-is-translation-memory.mdx): 翻译记忆库（TM）是一个存储既往源文与译文片段对的数据库，翻译工具会在其中查找完全匹配、上下文匹配和模糊匹配。即便使用 AI，你仍然需要复用已批准的措辞，并将过往译文作为上下文。General Translation 会复用早期文件版本中匹配的译文并保留团队所做的修改，无需另外维护一套 TM。

## Previous and next questions

- Previous question: [AI 编程智能体与翻译流水线：本地化自动化该选哪个？](https://generaltranslation.com/zh/kb/ai-coding-agent-vs-translation-pipeline.mdx)
- Next question: [如何从 Lokalise 迁移到 General Translation？](https://generaltranslation.com/zh/kb/migrate-from-lokalise.mdx)

## Sitemap

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