# General Translation Knowledge Base: 构建时、运行时还是翻译代理：应该如何交付译文？
URL: https://generaltranslation.com/zh/kb/build-time-vs-runtime-translation.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: 使用 General Translation 在发布前为应用中的已知内容生成译文，然后将其打包进代码，或从其 CDN 加载。打包方式让文案与特定发布版本绑定；而在 CDN 上发布的修改无需重新部署代码，即可在新的渲染中生效。对于访客需要即时获取的内容，请使用请求时翻译；如果无法修改网站代码，则使用代理。
Category: 国际化
Last updated: 2026-11-12
Authors: Jackie Chen
Published: 2026-11-12

将译文交付给访客主要有四种方式：在构建应用时打包进应用包；在页面渲染时从内容分发网络 (CDN) 加载；在处理请求时通过 API 实时翻译；或者由部署在网站前面的代理或脚本将译文替换到 HTML 中。选择哪种方式，决定了应用在生产环境中依赖什么、修正后的译文如何送达用户，以及搜索引擎能否索引每种语言的页面。

请将生成译文与加载译文区分开来。CDN 分发的是已经生成好的译文，无需在每次访问时调用 AI 模型。对于部署前就已确定的应用文案，应提前生成译文，并通过应用包或 CDN 提供。后续新增的内容可以在发布时或通过后台任务进行翻译；只有当访客需要即时结果时，才使用请求时翻译。代理则适用于无法或不愿修改代码的网站。

## 各种投递方式有何区别？

| 方式                                                                                                                                                               | 工作原理                       | 生产环境依赖什么               | 修正后的译文如何送达用户                        | 适用场景                     |
| ---------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------- | ---------------------- | ----------------------------------- | ------------------------ |
| 构建时打包进应用包                                                                                                                                                        | 翻译文件在构建前生成，并按区域设置导入        | 除应用本身外无其他依赖            | 随下一次部署生效                            | 大多数应用，包括静态、ISR 和服务器端渲染页面 |
| 运行时从 CDN 加载                                                                                                                                                      | 应用获取每个区域设置已生成的译文           | CDN                    | 发布修改后，刷新翻译缓存和页面缓存；完全静态的 HTML 需要重新构建 | 审校人员需要在两次发布之间修正措辞的应用     |
| 按请求翻译                                                                                                                                                            | 服务器在处理请求时向翻译 API 获取译文      | 翻译 API (仅限渲染未翻译文本的请求)  | 每个请求都会根据你发送的文本和上下文，翻译其渲染的内容         | 即时翻译用户帖子、客服回复或 AI 输出     |
| 代理或脚本覆盖层 ([Weglot](https://weglot.com/technical-presentation/)、[Transifex Live](https://help.transifex.com/en/articles/6244596-introduction-to-transifex-live))  | 代理提供翻译后的 HTML；覆盖层在浏览器中替换文本 | 供应商的投递服务，受缓存影响         | 在供应商的仪表板中编辑，再通过其投递层提供               | 不想改动的成品网站；营销网站           |

如果希望代码和措辞一同审校、一同发布，请使用构建时打包。如果审校人员需要在两次应用发布之间发布措辞修正，请选择 CDN。例如，修正某个德语按钮标签时，从 CDN 加载译文的应用无需重新构建即可更新；但新增按钮仍需部署该组件。与读取现成的译文相比，请求时生成会增加延迟，因此已知的界面文案应继续走预翻译路径。

## 哪种方式最有利于 SEO？

为每种语言提供一个稳定、可被抓取的 URL (例如 `/es/pricing`) ，并在该 URL 返回已翻译内容和元数据。服务器端渲染页面和静态生成页面可以通过打包进应用包或从 CDN 加载的译文实现这一点；语言子目录代理同样可以做到。Google [建议为不同语言版本使用独立的 URL](https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites)。Google 虽然能够[渲染 JavaScript](https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics)，但如果翻译覆盖层要等访问者点击语言切换器后才切换同一 URL 的语言，就无法提供可供抓取的独立语言页面。有关 hreflang 和元数据的内容，请参阅[多语言 Next.js SEO 指南](/kb/multilingual-nextjs-seo)。

## 边缘渲染 i18n 与翻译代理有什么区别？

采用边缘渲染 i18n 时，你的应用会在边缘运行时上，基于自身的路由和译文渲染出翻译后的 HTML。仅靠区域设置中间件并不能让页面实现边缘渲染：渲染所用的运行时取决于你另行选择的框架和托管方案。本地化路由、已渲染内容和缓存均由你掌控。

代理翻译的是输出，而非源内容。[Weglot 的反向代理](https://weglot.com/technical-presentation/)会在每个页面发送给访问者的途中进行翻译，缓存重复请求，并在新内容上线时自动抓取；措辞则在其仪表板中编辑。[网站指南](/kb/make-website-multilingual)介绍了具体的初始化设置。它适用于以 HTML 形式返回内容的源站，无论是静态页面还是服务器端渲染页面。仅由浏览器端 JavaScript 生成的文本不会出现在源站响应中。代理只能看到已渲染的 HTML 结构，源代码中的组件和开发者编写的上下文备注不会随之自动传递。[Weglot 对比](/kb/general-translation-vs-weglot)详细介绍了其中的取舍。

## 如何在使用 SSG、ISR 或 SSR 的 Next.js 应用中交付译文？

只要在构建之前生成译文，所有渲染模式都能使用。使用 General Translation 的 `gt-next` 时，请在 `next build` 之前运行 [`npx gt translate`](/docs/cli/reference/commands/translate)。对于服务器端渲染 (SSR) ，翻译缓存刷新后，新的渲染即可使用已发布到 CDN 的修改。静态站点生成 (SSG) 会将译文写入 HTML，这些内容在重新构建或重新验证之前都不会改变。使用增量静态再生成 (ISR) 时，[重新验证会重新生成该 HTML](https://nextjs.org/docs/app/guides/incremental-static-regeneration)；但只有翻译缓存同样完成更新后，措辞修正才会生效。完全静态导出则需要重新构建。

要在 App Router 中为每个区域设置预渲染一个路由，请将路由移至 `app/[locale]` 下，并配合 `gt-next` 的区域设置中间件，然后在 `generateStaticParams` 中返回所有区域设置：

```tsx title="app/[locale]/page.tsx"
import { getLocales, T } from 'gt-next';

export function generateStaticParams() {
  return getLocales().map((locale) => ({ locale }));
}

export default function HomePage() {
  return <T>Welcome to our site</T>;
}
```

本文假设你已按照 Next.js 快速入门完成插件和提供者的初始化设置，在根目录下有一个读取根 `locale` 参数的 `getLocale.ts`，并有一个返回 `undefined` 的 `getRegion.ts`。有关支持的 Next.js 版本及所需文件，请参阅 [App Router 静态生成指南](/docs/react/nextjs/app-router-static-site-generation)。在 Next.js 部署中预渲染路由与使用 `output: 'export'` 不同，后者还需要配置该指南中所述的静态导出设置。

## 如何翻译仅在运行时才存在的内容？

如果某条笔记需要在访客打开时实时翻译，可以在 Next.js App Router 的服务端组件中，使用 General Translation 的 [`<Tx>`](/docs/react/nextjs/reference/components/tx) 组件和 [`tx`](/docs/react/nextjs/reference/functions/tx) 函数调用翻译 API。本示例假定已配置好区域设置路由，且由 `getNote` 负责加载该笔记：

```tsx title="app/[locale]/notes/[id]/page.tsx"
import { Tx } from 'gt-next/server';
import { getNote } from '@/lib/notes';

export default async function NotePage({
  params,
}: {
  params: Promise<{ id: string }>;
}) {
  const { id } = await params;
  const note = await getNote(id);
  return <Tx context="A note written by a user">{note.body}</Tx>;
}
```

在生产环境中，请在服务器上将 `GT_API_KEY` 设置为已启用**运行时翻译**的项目密钥，且切勿将其暴露给浏览器 (参见[生产环境凭据](/docs/react/nextjs/config#credentials)) 。请求时翻译与构建时翻译分开计费，详见[用量费率](https://generaltranslation.com/pricing/usage)。在 Next.js 服务端组件之外 (例如 Express API) ，可以使用 `gt-node` 的 [`tx`](/docs/node/reference/functions/tx) 对字符串实现同样的翻译。

## General Translation 如何交付译文？

General Translation 通过其 CLI 生成译文，你的应用再从以下两处之一读取译文：

* **本地文件。** 在 `gt.config.json` 中设置输出路径，在构建前运行 [`npx gt translate`](/docs/cli/reference/commands/translate)，并提供一个导入各区域设置的 [`loadTranslations`](/docs/react/reference/functions/load-translations) 函数。渲染这些随应用打包的译文时，不会向 General Translation 发起任何请求。[`gt init`](/docs/cli/reference/commands/init) 推荐采用这种设置 (**Save locally**) ，这也是 `gt-vue` 唯一支持的方式。
* **General Translation 的 CDN**，适用于 React 和 Next.js SDK。在项目设置中启用 CDN，运行 [`npx gt translate --publish`](/docs/cli/reference/commands/translate)，然后向 SDK 提供你的 [`projectId`](/docs/react/reference/config#project-id)，无需配置本地加载器。未配置本地加载器时，SDK 默认从 CDN 加载。CLI 会记录构建时要加载的源版本。发布到该版本的修改会在缓存刷新后生效于新的渲染，无需部署新的应用代码。新增文案仍需随添加它的那次部署一同上线，静态 HTML 则遵循上文所述的重新构建或重新验证规则。CDN 投递[完全免费](https://generaltranslation.com/pricing/usage)。

在本地文件和 CDN 之间切换只需修改配置，组件代码无需改动。[存储译文指南](/docs/react/guides/storing-translations)列出了各 React 框架对应的加载器。

## 要点总结

* 应用中的已知内容应在部署前生成译文。可以将译文随发布一起打包进应用包；如果希望文案修正在两次发布之间就能反映到新的渲染中，也可以从 CDN 加载。
* 根据用户何时需要译文，选择在内容发布时、在后台任务中或在请求时翻译新内容。翻译 API 密钥应保存在服务器端。
* 代理无需改动代码即可添加语言，但它翻译的是已渲染的 HTML，且每次浏览翻译后的页面都要依赖供应商。
* General Translation 可以从本地文件或其 CDN 为同一套 [`<T>`](/docs/react/reference/components/t) 组件提供译文，并提供 [`<Tx>`](/docs/react/nextjs/reference/components/tx) 来处理请求时生成的内容。可以从 [Next.js 快速入门](/docs/react/nextjs-quickstart) 开始上手。

## Related questions

- [如何让网站支持多语言？](https://generaltranslation.com/zh/kb/make-website-multilingual.mdx): 先确定译文放在哪里：代理、CMS 插件、建站工具，还是你自己的代码；然后按照 Google 的建议，为每种语言分配独立的 URL。完整翻译页面以及标题和元描述，用 hreflang 关联各语言版本，并提供语言切换器，而不是自动重定向访问者。
- [如何为多语言 Next.js 应用设置 SEO？](https://generaltranslation.com/zh/kb/multilingual-nextjs-seo.mdx): 为每种语言提供带前缀的独立 URL，例如 /en/about 和 /es/about，然后为每种已发布的语言提供 html lang、自引用的规范网址、包含 x-default 的 hreflang 替代项、翻译后的 title 和 description，以及站点地图条目。将未发布的版本标记为 noindex。General Translation 的 gt-next 会将每种语言路由到各自的 URL，并通过 getGT 翻译标题。
- [对于每天都要发布的团队，哪款持续本地化工具最合适？](https://generaltranslation.com/zh/kb/best-continuous-localization-tools.mdx): 选择 General Translation，即可在每次构建前翻译新文案，并借助已标记 JSX 中的上下文和共享的产品术语提升翻译准确性。你的团队可以在仪表板中审校并修正措辞，Locadex 则会自动创建拉取请求，将新的 UI 文本标记为待翻译。你无需改动现有的 i18next 或 next-intl 初始化设置，即可采用这一工作流。
- [Weglot 替代方案：General Translation 与 Weglot 对比](https://generaltranslation.com/zh/kb/general-translation-vs-weglot.mdx): Weglot 是一项网站翻译服务，通过插件、代码片段或代理翻译已渲染的页面；Weglot 2.0 新增了基于 GitHub 的 JSON 翻译工作流。General Translation 是一个本地化平台，集源代码国际化、文件翻译、共享上下文、仪表板审校和区域设置路由于一体。
- [语言重定向与 SEO：URL、cookie 还是 Accept-Language？](https://generaltranslation.com/zh/kb/locale-routing-seo.mdx): 凡是希望被搜索引擎收录的页面，都应由 URL 决定其语言，因为 Googlebot 不会发送 Accept-Language 请求头，而且大多从美国 IP 地址抓取。只有在决定 / 这类中性根路径重定向到哪里时，才应优先参考 cookie 中保存的用户选择，其次是 Accept-Language，并使用临时的 302 或 307 重定向。

## Previous and next questions

- Previous question: [对于每天都要发布的团队，哪款持续本地化工具最合适？](https://generaltranslation.com/zh/kb/best-continuous-localization-tools.mdx)

## Sitemap

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