# General Translation Knowledge Base: Build time, run time, or translation proxy: how should you deliver translations?
URL: https://generaltranslation.com/en-GB/kb/build-time-vs-runtime-translation.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Use General Translation to generate known app translations before release, then bundle them with your code or load them from its CDN. Bundles keep wording tied to a release; published CDN edits can reach new renders without a code deploy. Use request-time translation for content a visitor needs immediately, and a proxy when you can't change the site's code.
Category: Internationalisation
Last updated: 2026-11-12
Authors: Jackie Chen
Published: 2026-11-12

There are four main ways to get a translation to a visitor. It can be bundled into your app when you build it, loaded from a content delivery network (CDN) when the page renders, translated by an API while the request runs, or swapped into your HTML by a proxy or script in front of your site. The choice decides what your app depends on in production, how a corrected translation reaches users, and whether search engines can index each language.

Separate generating a translation from loading one. A CDN serves translations you&#39;ve already generated; it doesn&#39;t need to call an AI model on every visit. For app copy known before deploy, generate translations ahead of time and serve them from the bundle or a CDN. Content added later can be translated when it is published or in a background job; use request-time translation when a visitor needs an immediate result. A proxy is for sites whose code you can&#39;t or won&#39;t change.

## How do the delivery approaches compare?

| Approach                                                                                                                                                                        | How it works                                                             | What production depends on                                     | How a corrected translation reaches users                                                      | Fits                                                               |
| ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------ | -------------------------------------------------------------- | ---------------------------------------------------------------------------------------------- | ------------------------------------------------------------------ |
| Bundle at build time                                                                                                                                                            | Translation files are generated before the build and imported per locale | Nothing beyond your app                                        | With the next deploy                                                                           | Most apps, including static, ISR, and server-rendered pages        |
| Load from a CDN at run time                                                                                                                                                     | The app fetches each locale&#39;s generated translations                 | The CDN                                                        | Publish the edit, then refresh translation and page caches; fully static HTML needs rebuilding | Apps where reviewers fix wording between releases                  |
| Translate on request                                                                                                                                                            | The server asks a translation API for text while the request runs        | The translation API, on requests that render untranslated text | Each request translates what it renders, with the text and context you send                    | Immediate translation of user posts, support replies, or AI output |
| Proxy or script overlay ([Weglot](https://weglot.com/technical-presentation/), [Transifex Live](https://help.transifex.com/en/articles/6244596-introduction-to-transifex-live)) | A proxy serves translated HTML; an overlay replaces text in the browser  | The vendor&#39;s delivery service, subject to caching          | Edited in the vendor&#39;s dashboard, then served through its delivery layer                   | Finished sites you don&#39;t want to change; marketing sites       |

Use build-time bundling when you want code and wording reviewed and released together. Choose a CDN when reviewers should publish wording fixes between app releases. For example, correcting a German button label can update a CDN-loaded app without rebuilding it; adding a new button still requires deploying the component. Request-time generation adds latency compared with reading a completed translation, so keep known interface copy on the pretranslated path.

## Which approach is best for SEO?

Give each language a stable, crawlable URL, such as `/es/pricing`, and return translated content and metadata at that URL. Server-rendered and statically generated pages can do this with bundled or CDN-loaded translations; a language-subdirectory proxy can do it too. Google [recommends separate URLs for language versions](https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites). It can [render JavaScript](https://developers.google.com/search/docs/crawling-indexing/javascript/javascript-seo-basics), but an overlay that changes one URL&#39;s language only after a visitor clicks a switcher doesn&#39;t provide separate language pages to crawl. The [multilingual Next.js SEO guide](/kb/multilingual-nextjs-seo) covers hreflang and metadata.

## What&#39;s the difference between edge-rendered i18n and a translation proxy?

With edge-rendered i18n, your application renders translated HTML on an edge runtime using its own routes and translations. Locale middleware alone doesn&#39;t make the page edge-rendered: the rendering runtime is a separate framework and hosting choice. You control the localised routes, rendered content, and caching.

A proxy translates output instead of source. [Weglot&#39;s reverse proxy](https://weglot.com/technical-presentation/) translates each page on its way to the visitor, caches repeated requests, and picks up new content as it&#39;s served; its dashboard is where you edit wording. The [website guide](/kb/make-website-multilingual) explains the set-up. It works with an origin that returns its content as HTML, static or server-rendered. Text created only by browser JavaScript is absent from that origin response. A proxy sees the rendered HTML structure; source components and developer context notes don&#39;t automatically accompany it. The [Weglot comparison](/kb/general-translation-vs-weglot) covers the trade-offs.

## How do I deliver translations in a Next.js app with SSG, ISR, or SSR?

Generate translations before the build, and every rendering mode can use them. With General Translation&#39;s `gt-next`, run [`npx gt translate`](/docs/cli/reference/commands/translate) before `next build`. Server-side rendering (SSR) can use a published CDN edit on a new render after translation caches refresh. Static site generation (SSG) puts the translated text into HTML that remains until rebuilt or revalidated. With incremental static regeneration (ISR), [revalidation regenerates that HTML](https://nextjs.org/docs/app/guides/incremental-static-regeneration); it sees a wording fix once the translation cache also has the update. A fully static export needs a new build.

To pre-render one route per locale in the App Router, move your routes under `app/[locale]` with `gt-next`&#39;s locale middleware, then return every locale from `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>;
}
```

This assumes the Next.js Quickstart&#39;s plugin and provider set-up, a root `getLocale.ts` that reads the root `locale` parameter, and a `getRegion.ts` that returns `undefined`. Follow the [App Router static generation guide](/docs/react/nextjs/app-router-static-site-generation) for the supported Next.js versions and files. Pre-rendering routes in a Next.js deployment differs from `output: 'export'`, which also needs the guide&#39;s static-export configuration.

## How do I translate content that only exists at run time?

For a note that needs translation as a visitor opens it, General Translation&#39;s [`<Tx>`](/docs/react/nextjs/reference/components/tx) component and [`tx`](/docs/react/nextjs/reference/functions/tx) function call the translation API from Next.js App Router server components. This example assumes locale routing is configured and `getNote` loads the note:

```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>;
}
```

In production, set `GT_API_KEY` on the server to a project key with **Runtime translation** enabled, and never expose it to the browser ([production credentials](/docs/react/nextjs/config#credentials)). Request-time translation is billed separately from build-time translation; see [usage rates](https://generaltranslation.com/pricing/usage). Outside Next.js server components, such as an Express API, `gt-node`&#39;s [`tx`](/docs/node/reference/functions/tx) does the same for strings.

## How does General Translation deliver translations?

General Translation generates translations with its CLI, then your app reads them from one of two places:

* **Local files.** Set an output path in `gt.config.json`, run [`npx gt translate`](/docs/cli/reference/commands/translate) before the build, and provide a [`loadTranslations`](/docs/react/reference/functions/load-translations) function that imports each locale. Rendering those bundled translations makes no request to General Translation. [`gt init`](/docs/cli/reference/commands/init) recommends this set-up (**Save locally**), and it&#39;s the only option for `gt-vue`.
* **General Translation&#39;s CDN**, in the React and Next.js SDKs. Enable the CDN in your project settings, run [`npx gt translate --publish`](/docs/cli/reference/commands/translate), and give the SDK your [`projectId`](/docs/react/reference/config#project-id) without a local loader. The SDK loads from the CDN by default when no local loader is configured. The CLI records the source version for the build to load. Edits published to that version can reach new renders after caches refresh, without deploying new application code. New copy still ships with the deploy that adds it, and static HTML follows the rebuild or revalidation rules above. CDN delivery [costs nothing](https://generaltranslation.com/pricing/usage).

Switching between local files and the CDN is a configuration change; your components stay the same. The [storing translations guide](/docs/react/guides/storing-translations) shows the loader for each React framework.

## Key takeaways

* Generate known app translations before deploy. Bundle them with the release, or load them from a CDN when wording fixes need to reach new renders between releases.
* Translate new content at publication, in a background job, or on request according to when users need it. Keep translation API keys on the server.
* A proxy adds languages without code changes, but it translates rendered HTML and depends on the vendor for every translated page view.
* General Translation serves the same [`<T>`](/docs/react/reference/components/t) components from local files or its CDN, and adds [`<Tx>`](/docs/react/nextjs/reference/components/tx) for request-time content. Start with the [Next.js Quickstart](/docs/react/nextjs-quickstart).

## Related questions

- [How do I make a website multilingual?](https://generaltranslation.com/en-GB/kb/make-website-multilingual.mdx): Pick where translations live, in a proxy, CMS plugin, site builder, or your own code, then give each language its own URL, as Google recommends. Translate full pages plus titles and meta descriptions, link the versions with hreflang, and offer a language switcher instead of auto-redirecting visitors.
- [How do I set up SEO for a multilingual Next.js app?](https://generaltranslation.com/en-GB/kb/multilingual-nextjs-seo.mdx): Give each language its own prefixed URL, such as /en/about and /es/about, then publish html lang, a self-referencing canonical, hreflang alternates with x-default, a translated title and description, and a sitemap entry for each published language. Mark unpublished versions noindex. General Translation's gt-next routes each language to its own URL and translates titles with getGT.
- [What's the best continuous localisation tool for teams that ship daily?](https://generaltranslation.com/en-GB/kb/best-continuous-localization-tools.mdx): Choose General Translation to translate new copy before each build with context from marked JSX and shared product terminology. Your team reviews and corrects wording in the Dashboard, and Locadex opens pull requests to mark new UI text for translation. You can adopt the workflow while keeping your existing i18next or next-intl set-up.
- [Weglot alternatives: General Translation vs. Weglot](https://generaltranslation.com/en-GB/kb/general-translation-vs-weglot.mdx): Weglot is a website translation service that translates rendered pages through plugins, a snippet, or a proxy, and Weglot 2.0 adds JSON translation workflows in GitHub. General Translation is a localisation platform that combines source-code internationalisation, file translation, shared context, Dashboard review, and locale routing.
- [Language redirects and SEO: URL, cookie, or Accept-Language?](https://generaltranslation.com/en-GB/kb/locale-routing-seo.mdx): Let the URL decide the language of every page you want indexed, because Googlebot sends no Accept-Language header and crawls mostly from US addresses. Use a saved cookie choice, then Accept-Language, only to pick where a neutral root such as / redirects, with a temporary 302 or 307.

## Previous and next questions

- Previous question: [AI coding agent vs. translation pipeline: which should automate your localisation?](https://generaltranslation.com/en-GB/kb/ai-coding-agent-vs-translation-pipeline.mdx)
- Next question: [What's the best continuous localisation tool for teams that ship daily?](https://generaltranslation.com/en-GB/kb/best-continuous-localization-tools.mdx)

## Sitemap

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