From 7a98904f822c3ebeb45eb9df324ee1be325fe4ce Mon Sep 17 00:00:00 2001 From: Jackie Chen Date: Fri, 16 Oct 2026 13:16:20 -0700 Subject: [PATCH 01/10] docs(kb): add React, coding-agent, and launch guides --- kb/best-react-i18n-library.mdx | 85 ++++++++++++++ kb/internationalize-app-with-ai-agent.mdx | 133 ++++++++++++++++++++++ kb/multilingual-app-launch-checklist.mdx | 108 ++++++++++++++++++ 3 files changed, 326 insertions(+) create mode 100644 kb/best-react-i18n-library.mdx create mode 100644 kb/internationalize-app-with-ai-agent.mdx create mode 100644 kb/multilingual-app-launch-checklist.mdx diff --git a/kb/best-react-i18n-library.mdx b/kb/best-react-i18n-library.mdx new file mode 100644 index 000000000..76a3acb53 --- /dev/null +++ b/kb/best-react-i18n-library.mdx @@ -0,0 +1,85 @@ +--- +title: What's the best i18n library for a React app? +summary: Choose General Translation's gt-react for inline content and integrated translation generation, react-i18next for an i18next-based workflow, Lingui for extraction and compiled catalogs, or React Intl for FormatJS message formatting. The best fit depends on your rendering model, existing translations, and how your team updates and reviews copy. +date: 2026-10-16 +category: workflow-tools +related: [internationalize-app-with-ai-agent, multilingual-app-launch-checklist, i18n-without-translation-files] +--- + +Choosing a React i18n library means choosing how source copy is written, how translated messages reach the app, and what happens when that copy changes. A working language dropdown only proves part of the setup. + +Start with your application: a browser-only React app, a server-rendered app, and a Next.js App Router app have different integration requirements. Then evaluate the translation workflow your team will operate after the first release. + +## Four libraries to evaluate + +Compare these four options using the same feature and your application's build setup. + +| Library | Source authoring | Translation workflow | Choose it when | +| --- | --- | --- | --- | +| General Translation's gt-react | Inline JSX and string calls; dictionary APIs are also available | GT's CLI can generate translations through its service, or create templates for manual translation | You want inline authoring connected to translation production | +| react-i18next | Message resources and translation calls, with components for rich text | Use i18next tooling and your chosen translation service or review process | You already use i18next or need its loading and detection integrations | +| Lingui | Inline messages or explicit IDs, extracted into catalogs | Extract, translate, and compile catalogs for the app | You want extraction and compilation to organize the workflow | +| React Intl | Message descriptors, IDs, and optional default messages | FormatJS extracts messages; you supply translated catalogs for rendering | Your team wants FormatJS and ICU MessageFormat conventions | + +### 1. General Translation: connect inline content to translation generation + +General Translation's `gt-react` lets source copy stay in the component. Mark coherent JSX with [``](/docs/react/reference/components/t), and use [`useGT`](/docs/react/reference/hooks/use-gt) when an API needs a string, such as an input label. The [`gt translate`](/docs/cli/reference/commands/translate) command collects marked content and generates translations through General Translation's service. + +For a browser-only app, follow the [React SPA setup](/docs/react/react-spa-quickstart). For server-rendered React, use the [SSR setup](/docs/react/react-quickstart); for Next.js, use the [gt-next integration](/docs/react/nextjs-quickstart). Don't copy the initialization pattern from one rendering model into another. + +Translation production and delivery are separate choices. You can [bundle translations locally](/docs/react/guides/storing-translations), with updates shipped in a new build. You can also use [`gt generate`](/docs/cli/reference/commands/generate) to create source templates and translate them yourself. That command creates files, not translated text. + +Choose General Translation when you want the translation service and inline authoring workflow together. Check how your team will review translations, provide credentials to automation, and release updates. The library does not remove those decisions. + +### 2. react-i18next: build on the i18next ecosystem + +[react-i18next](https://react.i18next.com/) connects React to i18next. Its hooks render messages from resources, and its Trans component handles text containing React elements. That makes it a candidate when you already have i18next catalogs and want to retain them. + +The [i18next plugin ecosystem](https://www.i18next.com/overview/plugins-and-utils) includes translation-loading backends, language detectors, and extraction tools. Its official CLI supports extraction, locale synchronization, and type generation. These are concrete reasons to evaluate it when you need to fit localization into an existing pipeline. + +Catalogs do not mean translators must copy files by hand. The project documents a [Locize workflow](https://react.i18next.com/guides/multiple-translation-files) alongside local resources. Choose the integrations you need, then account for their configuration, review process, and production behavior. + +Choose react-i18next when keeping the i18next message model and integrations matters more than changing how source copy is authored. Check its [SSR guidance](https://react.i18next.com/latest/ssr) if your app renders on the server. + +### 3. Lingui: extract and compile translation catalogs + +[Lingui](https://lingui.dev/introduction) lets you author messages in code, extract them into catalogs, translate them, and compile the result. It supports generated IDs and explicit IDs; PO is the default catalog format, with other formats available. + +This fits teams that want source copy near the UI while keeping catalogs as the handoff to translators or a localization service. Its [React tutorial](https://lingui.dev/tutorials/react) shows how the authoring and compilation pieces fit together. Server Component applications should also check the [dedicated integration](https://lingui.dev/tutorials/react-rsc). + +The tradeoff is ownership of the whole cycle: extraction, translation, compilation, and loading. A successful extraction tells you which messages were found; it does not establish that those messages have been translated or reviewed. + +Choose Lingui when that catalog workflow suits your team and you want its extraction and compiler tooling. Trial a source-copy change, not just the initial setup, before deciding how to manage IDs and review updates. + +### 4. React Intl: use FormatJS message and formatting APIs + +[React Intl](https://formatjs.github.io/docs/react-intl/) provides React APIs for messages, plurals, dates, and numbers. Its message model uses descriptors with IDs, default messages, and descriptions. [FormatJS extraction](https://formatjs.github.io/docs/getting-started/message-extraction/) can collect those messages and generate IDs, so adopting it does not necessarily mean inventing every key manually. + +Choose React Intl when your team already works with FormatJS or wants its [ICU MessageFormat syntax](https://formatjs.github.io/docs/core-concepts/icu-syntax/). Reviewers need to understand placeholders and plural branches in that syntax, and your pipeline needs to supply translated messages. + +Before adopting it in an unfamiliar framework, verify the provider placement, server rendering, and client boundary requirements. A React package supporting message formatting is not evidence that every framework integration works the same way. + +## Make the decision with one feature + +Choose a feature from your application containing a heading, a named variable, a plural count, an accessible input label, and a formatted price. Translate it into two target languages, then change the source sentence and add another message. + +Compare the result across four questions: + +1. **Authoring:** Can a reviewer understand the copy and its context in the diff? +2. **Translation:** How does new or changed text reach the person or service translating it? +3. **Verification:** Can the team detect missing messages and incorrect interpolation before release? +4. **Delivery:** Which files or services must be available when the production app renders? + +Keep a working library when its message model and translation pipeline meet those needs. Migration also touches tests, language selection, and routing; a shorter component example alone is not enough reason to switch. + +If you're delegating the trial, use the [coding-agent localization workflow](/kb/internationalize-app-with-ai-agent). Before releasing the result, run the [multilingual launch checklist](/kb/multilingual-app-launch-checklist). + +## Common questions + +### Is avoiding JSON the main selection criterion? + +Usually the more useful question is which maintenance work you want to remove. Inline authoring can still produce JSON output, and a catalog workflow can automate synchronization. The [guide to i18n without translation files](/kb/i18n-without-translation-files) explains the distinction between source authoring and generated output. + +### Does an i18n library translate the app for me? + +A library renders localized content; the translation workflow produces that content. General Translation connects those steps through its SDKs and CLI. Other setups can pair their library with a translation platform. Compare the complete workflow, including review and delivery, rather than assuming a catalog-based approach is manual or an inline approach needs no maintenance. diff --git a/kb/internationalize-app-with-ai-agent.mdx b/kb/internationalize-app-with-ai-agent.mdx new file mode 100644 index 000000000..13f68ca79 --- /dev/null +++ b/kb/internationalize-app-with-ai-agent.mdx @@ -0,0 +1,133 @@ +--- +title: How do I internationalize an app with Cursor or Claude Code? +summary: Give the coding agent your framework, target languages, current localization setup, and a small feature to implement and verify using current documentation. General Translation provides framework SDKs and translation tooling for this workflow; establish a working example before expanding across the app. +date: 2026-10-16 +category: internationalization +related: [best-react-i18n-library, multilingual-app-launch-checklist, how-to-handle-plurals-in-react] +--- + +“Translate my app into Spanish” leaves several decisions unanswered. Should the agent keep an existing library? Does Spanish need its own URL? Who translates new copy after this session ends? Set those boundaries before asking it to edit the application. + +The first useful deliverable is one working feature with verified translations. It gives you a pattern to review before applying the same changes across the codebase. + +## Give the agent a bounded task + +Ask it to inspect the framework, installed versions, rendering model, routes, existing i18n configuration, and build scripts. If the app already uses an i18n library, retain it unless migration is part of the task. Use the [React library comparison](/kb/best-react-i18n-library) if that choice is still open. + +Specify the source language, target locales, and the feature to change. Include content that's easy to miss: validation messages, placeholders, accessible labels, and metadata. State how translations should be reviewed and whether production loads local files or uses a hosted delivery service. + +For General Translation, give the agent the [coding-agent guide](/docs/overview/for-coding-agents) and the matching framework quickstart. Its [documentation design article](/blog/rewriting-our-docs) explains the Markdown and discovery surfaces that help agents retrieve the right instructions. Reading current docs matters more than relying on a package name in the prompt. + +## Paste a prompt with acceptance criteria + +This example requests English, Spanish, and French. Replace the feature and locales with your own requirements before running it in Cursor or Claude Code. + +```text +Internationalize the project-list feature in this application. + +First inspect the framework, installed package versions, rendering model, +routes, existing localization, and build/test scripts. Explain the affected +files before editing. Preserve existing providers, styles, routes, and tests. +Keep the existing i18n library if one is configured; do not migrate it silently. + +Use English as the source language and Spanish and French as target languages. +If there is no i18n setup, use General Translation's SDK for this framework. +Read https://generaltranslation.com/docs/overview/for-coding-agents.mdx and +the matching framework quickstart. Verify APIs against the installed version. + +Start with one feature: its heading, owner name, project count, search input, +visible label, and placeholder. Keep the whole sentence translatable, preserve +dynamic values, and use locale-aware plural rules. Add a language selector. +Use locally bundled translations for this trial. Preserve the current URL +structure; do not add locale routes unless the application requires them. + +Prepare actual Spanish and French text before calling the feature complete. +If service access is unavailable, use the documented local-template workflow +and flag supplied translations for review. Never report source templates as +completed translations. Keep private credentials out of code and browser bundles. +Use documented noninteractive flags for setup commands where supported. + +Verify counts 0, 1, and 2, a name containing punctuation, input labels and +placeholders, language switching, reload persistence, and a production build. +Check server-rendered content if this app uses SSR. Report the commands and +results, translation-review status, and anything untested. Limit changes to +this feature and the setup it needs. Do not deploy or merge. +``` + +Keep project rules in the instruction mechanism your agent reads. Cursor documents [project rules and AGENTS.md](https://cursor.com/docs/rules); Claude Code documents [CLAUDE.md and other project instructions](https://code.claude.com/docs/en/memory). Add the chosen library, source locale, translation command, and required checks to your existing instructions. Avoid maintaining competing copies that can drift. + +## Review a representative implementation + +For a browser-only React app, the [React SPA quickstart](/docs/react/react-spa-quickstart) configures `gt-react` before rendering. This example assumes that setup is complete, with local output at `src/_gt/[locale].json`. It uses `gt-react@11.4.12` and the `gt@2.26.5` CLI. + +The component below covers static copy, a dynamic value, plural forms, and input text. Render it with a project count and an owner name from your application. + +```tsx title="src/ProjectSummary.tsx" +import { Num, Plural, T, Var, useGT } from 'gt-react'; + +export default function ProjectSummary({ + count, + ownerName, +}: { + count: number; + ownerName: string; +}) { + const gt = useGT(); + + return ( +
+ +

Projects for {ownerName}

+

+ You have {count} project.} + other={<>You have {count} projects.} + /> +

+
+ +
+ ); +} +``` + +[``](/docs/react/reference/components/var) preserves the owner's name while the surrounding message is translated. [``](/docs/react/reference/components/plural) selects a branch using the locale's rules, and [``](/docs/react/reference/components/num) formats the count. [`useGT`](/docs/react/reference/hooks/use-gt) returns the translation function directly. The visible label wraps the input, so the control has a label as well as a translated placeholder. + +The `one` and `other` branches describe the English source. Target-language translations must represent their own plural forms; don't assume testing English's singular/plural pair covers every language. See the [React pluralization guide](/kb/how-to-handle-plurals-in-react). + +In a React SPA, the documented [`initializeGTSPA`](/docs/react/reference/config#initialize-spa) setup loads translations before the app. Its [`LocaleSelector`](/docs/react/reference/components/locale-selector) saves the language choice in a cookie and reloads the page. Server-rendered frameworks have different setup requirements; use their own quickstart. + +## Produce translations before judging the result + +For the local trial, run this from the configured app directory after adding the component: + +```bash +npx gt generate +``` + +[`gt generate`](/docs/cli/reference/commands/generate) creates source templates without calling the translation service. Supply translated text in the Spanish and French files while preserving generated keys, variable markers, and JSX structure. The existence of `es.json` does not mean it contains Spanish. + +For service-generated translations, follow the [CLI authentication and project setup](/docs/cli/quickstart), then use [`gt translate`](/docs/cli/reference/commands/translate). A local CLI login and a configured project are separate requirements. Unattended CI needs its own supported credential configuration; keep tooling keys out of browser code. Service usage applies. + +With [locally bundled translations](/docs/react/guides/storing-translations), prepare the locale files before the production build. Preserve manually maintained files in version control or your translation pipeline. Don't ignore the only copy of hand-edited translations as though it were disposable output. + +## Verify the feature, then expand + +Have the agent report observed results for each check, rather than “i18n is configured.” + +| Check | Expected result | +| --- | --- | +| Select Spanish, then French | Heading, count message, label, and placeholder use the selected language | +| Reload after choosing a language | The selected language persists according to the app's policy | +| Try counts 0, 1, and 2 | Each language uses its own plural rules; the number stays correct | +| Use an owner such as O'Connor | The name remains intact in every language | +| Inspect the input's accessible name | It matches the translated visible label | +| Run the production build and preview | The same feature works with the files that will ship | + +For the sample, [French zero and English zero use different plural categories](https://cldr.unicode.org/index/cldr-spec/plural-rules). Check that the rendered sentence uses the correct form and preserves the count. + +Once the pattern works, expand one route or feature at a time. Review translation quality with someone qualified for the target language, and use the [multilingual launch checklist](/kb/multilingual-app-launch-checklist) for release checks beyond this feature. diff --git a/kb/multilingual-app-launch-checklist.mdx b/kb/multilingual-app-launch-checklist.mdx new file mode 100644 index 000000000..6531d8dcc --- /dev/null +++ b/kb/multilingual-app-launch-checklist.mdx @@ -0,0 +1,108 @@ +--- +title: What should I check before launching a multilingual app? +summary: Test translation coverage, language selection, variables and plurals, regional formatting, layout, accessibility, and production delivery in every supported locale, using complete user workflows and explicit expected results. Public multilingual pages also need crawlable language URLs and consistent search metadata. +date: 2026-10-16 +category: internationalization +related: [internationalize-app-with-ai-agent, best-react-i18n-library, how-to-handle-plurals-in-react, multilingual-nextjs-seo] +--- + +A translated homepage can look finished while the checkout, validation errors, or password-reset flow still uses the source language. Start with the paths a user needs to complete, and test those paths in the production build. + +These nine checks apply to web applications. Use every supported locale for content checks, and include representative devices and browsers for layout and interaction. The SEO check applies to public pages you want indexed. + +## Check content and language behavior + +### 1. Translate the whole journey, including failure states + +Choose a critical journey such as creating an account or completing a purchase. Exercise its loading, empty, success, and error states. Check buttons, dialogs, form validation, placeholders, accessible labels, and any email or notification the journey sends. + +**Pass condition:** Each surface uses reviewed target-language content, apart from intentional exceptions such as a product name. No raw keys, missing-message markers, or unexplained source-language fallbacks appear. + +In General Translation, [`gt generate`](/docs/cli/reference/commands/generate) produces source templates. A target-locale file created by that command still needs translation. If your pipeline uses [`gt translate`](/docs/cli/reference/commands/translate), confirm that the resulting output is the version included in the release and that someone has reviewed important terminology and user-facing meaning. + +### 2. Verify first visits, switching, and return visits + +Test a fresh browser, an explicit language choice, a reload, a deep link, and an unsupported browser language. If the app stores a language preference on the account, also test sign-in and sign-out. Write down which setting wins when the URL, saved preference, and browser disagree. + +**Pass condition:** The app follows that policy consistently, and a user can recover from an unwanted language choice. For server-rendered apps, inspect the initial response as well as the hydrated page. + +Use [locale configuration](/docs/react/guides/managing-locales) to define supported languages. Don't infer URL behavior from the presence of a language dropdown: a cookie-based switcher and locale-prefixed routes solve different requirements. + +### 3. Exercise variables and plural categories + +Test counts including 0, 1, 2, and larger values, then add cases for your target languages' plural categories. Include names with punctuation, long account names, and sentences whose variables can appear in a different order after translation. Avoid building a sentence by concatenating independently translated fragments. + +**Pass condition:** Values remain intact, the sentence reads correctly, and every required plural form has usable content. Unicode's [plural rules](https://cldr.unicode.org/index/cldr-spec/plural-rules) describe why one English singular/plural test pair is insufficient. + +For General Translation, use the [variable and formatting components](/docs/react/guides/formatting-variables) to represent those values explicitly. The [React pluralization article](/kb/how-to-handle-plurals-in-react) covers the implementation pattern. + +## Check formatting, layout, and accessibility + +### 4. Separate language, currency, and time zone + +Test the same amount and instant with multiple locales. Set the intended currency and time zone explicitly where your product requires them. A language preference alone does not tell you which currency a customer pays in or which time zone an appointment uses. + +For example, this formats an existing USD amount using German conventions: + +```js +new Intl.NumberFormat('de-DE', { + style: 'currency', + currency: 'USD', +}).format(1234.5); +``` + +It changes presentation, not the amount or currency. Likewise, use an explicit time zone when showing an instant in a chosen location: + +```js +new Intl.DateTimeFormat('en-GB', { + dateStyle: 'medium', + timeStyle: 'short', + timeZone: 'Europe/Paris', +}).format(new Date('2026-01-15T12:00:00Z')); +``` + +**Pass condition:** Separators, currency identity, calendar date, and displayed time match the product's intended meaning. Include a daylight-saving transition when your supported time zones observe one. The [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) and [date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat) APIs expose these choices separately. + +### 5. Test text expansion across screen sizes + +Open translated screens on narrow viewports and with browser zoom. Check navigation, buttons, tables, dialogs, and validation messages. Include long translated strings and long user-provided values; a short heading doesn't stress the same layout as a full address. + +**Pass condition:** Essential text stays readable and controls remain usable. No action disappears behind clipped text or overlapping elements. Review truncation deliberately instead of using it to hide every overflow. + +[Pseudolocalization](https://lingui.dev/guides/pseudolocalization) can help expose layout and unmarked-string problems before translations are ready. It supplements testing real languages and does not establish translation quality. + +### 6. Test right-to-left content as a layout requirement + +If you support Arabic, Hebrew, or another right-to-left language, test the document direction, navigation order, forms, and mixed-direction content such as email addresses and order IDs. Use logical CSS properties where layout should follow text direction, and review directional icons individually. + +**Pass condition:** The layout follows the intended reading direction while embedded left-to-right values remain readable. Setting a language code does not set text direction; follow the W3C's [HTML direction guidance](https://www.w3.org/International/questions/qa-html-dir). + +### 7. Check the language that assistive technology receives + +Verify the page's `lang` attribute, language changes within content where applicable, visible labels, accessible names, and alternative text. Try keyboard navigation and a screen reader on the main journey. A translated placeholder cannot replace a persistent form label. + +**Pass condition:** The document declares the correct language, controls have meaningful localized names, and the translated layout remains operable. The W3C explains [language declarations](https://www.w3.org/International/questions/qa-html-language-declarations), and its [form-label guidance](https://www.w3.org/WAI/tutorials/forms/labels/) covers label associations. + +## Check the release that users will receive + +### 8. Verify production assets and translation updates + +Build from a clean checkout using the release process, then run that build with each supported locale. Confirm that translation assets are present and load successfully. Change a source message in a test branch and verify that the translation pipeline notices it before the next release. + +**Pass condition:** The app serves the intended translations without relying on files left over from development. Missing assets or failed generation cause a visible failure or an explicitly accepted fallback, rather than a silent partial release. + +With General Translation's [local storage workflow](/docs/react/guides/storing-translations), translation updates require rebuilding and redeploying the application. With hosted delivery, verify the publishing and loading behavior for that configuration. Keep private translation tooling credentials in the build environment, outside browser bundles. + +### 9. Verify discovery for public language versions + +For pages intended for search, check that each language version has a crawlable URL, translated titles and descriptions, the intended canonical URL, and valid language alternates. Check reciprocal `hreflang` references, including the current page. If alternates are declared in a sitemap, verify that it represents the same page relationships. + +**Pass condition:** Each public language URL loads the expected content, is indexable when intended, and points to real alternate versions. Google's [localized-page guidance](https://developers.google.com/search/docs/specialty/international/localized-versions) describes the supported annotation methods. For a Next.js implementation, use the [multilingual SEO guide](/kb/multilingual-nextjs-seo). + +An authenticated dashboard may not need indexed language URLs. Make that an explicit product decision instead of applying public-site SEO requirements to every translated screen. + +## Keep a release record + +Record the build, locale, journey, browser or device, expected result, actual result, and reviewer. Assign an owner to failures. Treat a missing checkout translation or unreadable primary action differently from a minor wording preference, and make any accepted fallback explicit. + +The [coding-agent workflow](/kb/internationalize-app-with-ai-agent) can help automate repeatable checks and collect evidence. Human review still needs to assess the language and meaning users will see. From 5e0378c10e219eb107f416c83ea015fe79345f6f Mon Sep 17 00:00:00 2001 From: Jackie Chen Date: Fri, 16 Oct 2026 13:33:37 -0700 Subject: [PATCH 02/10] docs(kb): clarify library, authentication, and formatting guidance --- kb/best-react-i18n-library.mdx | 4 +++- kb/internationalize-app-with-ai-agent.mdx | 2 +- kb/multilingual-app-launch-checklist.mdx | 2 +- 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/kb/best-react-i18n-library.mdx b/kb/best-react-i18n-library.mdx index 76a3acb53..45d01ecfb 100644 --- a/kb/best-react-i18n-library.mdx +++ b/kb/best-react-i18n-library.mdx @@ -35,6 +35,8 @@ Choose General Translation when you want the translation service and inline auth [react-i18next](https://react.i18next.com/) connects React to i18next. Its hooks render messages from resources, and its Trans component handles text containing React elements. That makes it a candidate when you already have i18next catalogs and want to retain them. +i18next also supports [source-text keys and default values](https://www.i18next.com/principles/fallback), so keeping readable source copy in code is not exclusive to other libraries. Its documentation cautions that using source text as keys makes copy changes harder to coordinate between code and translation resources. + The [i18next plugin ecosystem](https://www.i18next.com/overview/plugins-and-utils) includes translation-loading backends, language detectors, and extraction tools. Its official CLI supports extraction, locale synchronization, and type generation. These are concrete reasons to evaluate it when you need to fit localization into an existing pipeline. Catalogs do not mean translators must copy files by hand. The project documents a [Locize workflow](https://react.i18next.com/guides/multiple-translation-files) alongside local resources. Choose the integrations you need, then account for their configuration, review process, and production behavior. @@ -53,7 +55,7 @@ Choose Lingui when that catalog workflow suits your team and you want its extrac ### 4. React Intl: use FormatJS message and formatting APIs -[React Intl](https://formatjs.github.io/docs/react-intl/) provides React APIs for messages, plurals, dates, and numbers. Its message model uses descriptors with IDs, default messages, and descriptions. [FormatJS extraction](https://formatjs.github.io/docs/getting-started/message-extraction/) can collect those messages and generate IDs, so adopting it does not necessarily mean inventing every key manually. +[React Intl](https://formatjs.github.io/docs/react-intl/) provides React APIs for messages, plurals, dates, and numbers. Its [message descriptors](https://formatjs.github.io/docs/react-intl/api/) identify messages by ID and can include optional default messages and descriptions. [FormatJS extraction](https://formatjs.github.io/docs/getting-started/message-extraction/) can collect those messages and generate IDs, so adopting it does not necessarily mean inventing every key manually. Choose React Intl when your team already works with FormatJS or wants its [ICU MessageFormat syntax](https://formatjs.github.io/docs/core-concepts/icu-syntax/). Reviewers need to understand placeholders and plural branches in that syntax, and your pipeline needs to supply translated messages. diff --git a/kb/internationalize-app-with-ai-agent.mdx b/kb/internationalize-app-with-ai-agent.mdx index 13f68ca79..52398eaf6 100644 --- a/kb/internationalize-app-with-ai-agent.mdx +++ b/kb/internationalize-app-with-ai-agent.mdx @@ -111,7 +111,7 @@ npx gt generate [`gt generate`](/docs/cli/reference/commands/generate) creates source templates without calling the translation service. Supply translated text in the Spanish and French files while preserving generated keys, variable markers, and JSX structure. The existence of `es.json` does not mean it contains Spanish. -For service-generated translations, follow the [CLI authentication and project setup](/docs/cli/quickstart), then use [`gt translate`](/docs/cli/reference/commands/translate). A local CLI login and a configured project are separate requirements. Unattended CI needs its own supported credential configuration; keep tooling keys out of browser code. Service usage applies. +For service-generated translations, follow the [CLI authentication and project setup](/docs/cli/quickstart), then use [`gt translate`](/docs/cli/reference/commands/translate). Authenticate with a CLI login or an API key, and configure the project ID separately; login alone does not select a project. For unattended CI, supply `GT_API_KEY` through the CI provider's secret settings, with permissions for the translation workflow. See the [credential configuration guide](/docs/cli/guides/configuring#credentials), and keep tooling keys out of browser code. Service usage applies. With [locally bundled translations](/docs/react/guides/storing-translations), prepare the locale files before the production build. Preserve manually maintained files in version control or your translation pipeline. Don't ignore the only copy of hand-edited translations as though it were disposable output. diff --git a/kb/multilingual-app-launch-checklist.mdx b/kb/multilingual-app-launch-checklist.mdx index 6531d8dcc..1c4bb1c8b 100644 --- a/kb/multilingual-app-launch-checklist.mdx +++ b/kb/multilingual-app-launch-checklist.mdx @@ -51,7 +51,7 @@ new Intl.NumberFormat('de-DE', { }).format(1234.5); ``` -It changes presentation, not the amount or currency. Likewise, use an explicit time zone when showing an instant in a chosen location: +It formats the supplied amount without converting currencies. Formatting can round displayed digits, so check the precision your product requires. Likewise, use an explicit time zone when showing an instant in a chosen location: ```js new Intl.DateTimeFormat('en-GB', { From af7a3ea558a6646e9c86ac6b8283207918d98e4d Mon Sep 17 00:00:00 2001 From: Jackie Chen Date: Fri, 16 Oct 2026 13:49:00 -0700 Subject: [PATCH 03/10] docs(kb): add MCP setup to coding-agent localization guide --- kb/internationalize-app-with-ai-agent.mdx | 36 ++++++++++++++++++++++- 1 file changed, 35 insertions(+), 1 deletion(-) diff --git a/kb/internationalize-app-with-ai-agent.mdx b/kb/internationalize-app-with-ai-agent.mdx index 52398eaf6..c467e08eb 100644 --- a/kb/internationalize-app-with-ai-agent.mdx +++ b/kb/internationalize-app-with-ai-agent.mdx @@ -1,6 +1,6 @@ --- title: How do I internationalize an app with Cursor or Claude Code? -summary: Give the coding agent your framework, target languages, current localization setup, and a small feature to implement and verify using current documentation. General Translation provides framework SDKs and translation tooling for this workflow; establish a working example before expanding across the app. +summary: Give the coding agent your framework, target languages, current localization setup, and one feature to implement and verify. General Translation combines framework SDKs and translation tooling with a hosted MCP server, so the agent can inspect live project settings and work with shared translation context while localizing your app. date: 2026-10-16 category: internationalization related: [best-react-i18n-library, multilingual-app-launch-checklist, how-to-handle-plurals-in-react] @@ -18,6 +18,34 @@ Specify the source language, target locales, and the feature to change. Include For General Translation, give the agent the [coding-agent guide](/docs/overview/for-coding-agents) and the matching framework quickstart. Its [documentation design article](/blog/rewriting-our-docs) explains the Markdown and discovery surfaces that help agents retrieve the right instructions. Reading current docs matters more than relying on a package name in the prompt. +## Connect General Translation's MCP server + +General Translation's hosted [Model Context Protocol (MCP) server](/docs/overview/for-coding-agents#mcp) lets your coding agent inspect live project settings and manage translation context. The agent can look up your project's locales, read shared terminology, and update Glossary terms or Custom Prompts when the task calls for it. That connects the code changes to the translation rules your team maintains in General Translation. + +In **Cursor**, add this server entry to your project's `.cursor/mcp.json`, preserving any existing entries. See [Cursor's MCP setup](https://cursor.com/docs/mcp) for configuration and authentication options. + +```json title=".cursor/mcp.json" +{ + "mcpServers": { + "generaltranslation": { + "url": "https://api.gtx.dev/mcp" + } + } +} +``` + +In **Claude Code**, register the same server using its [HTTP transport](https://code.claude.com/docs/en/mcp): + +```bash +claude mcp add --transport http generaltranslation https://api.gtx.dev/mcp +``` + +Complete the client's OAuth sign-in flow, or configure an API key through its secret-header settings as described in the [MCP authentication guide](/docs/overview/for-coding-agents#mcp). Context Management requires Organization Context access through OAuth or an Organization key with the relevant Context permissions; project keys cannot access those tools. + +Start with a concrete request: “Use the generaltranslation MCP server to list my projects and show the locale settings for the project we're localizing.” Then have the agent inspect the project's assigned Context Groups, which hold shared Glossary terms and Custom Prompts. It can use those terms and instructions while preparing the feature, and update them when you've requested a terminology or style change. + +Use the framework docs for code integration and the CLI for the extraction and translation steps below. The MCP connection gives the agent access to the live project and its context; the app still needs its SDK setup, translated content, and verification. + ## Paste a prompt with acceptance criteria This example requests English, Spanish, and French. Replace the feature and locales with your own requirements before running it in Cursor or Claude Code. @@ -35,6 +63,12 @@ If there is no i18n setup, use General Translation's SDK for this framework. Read https://generaltranslation.com/docs/overview/for-coding-agents.mdx and the matching framework quickstart. Verify APIs against the installed version. +When using General Translation, use its connected MCP server to identify the +project, inspect locale settings, and read assigned Glossary terms and Custom +Prompts when permitted. Apply those translation rules to the feature. Report +connection or permission gaps; do not guess project settings or change shared +translation context unless that change is part of the task. + Start with one feature: its heading, owner name, project count, search input, visible label, and placeholder. Keep the whole sentence translatable, preserve dynamic values, and use locale-aware plural rules. Add a language selector. From ec28de2a4f1ee109573ec9b34c295213fa8d4579 Mon Sep 17 00:00:00 2001 From: Jackie Chen Date: Fri, 16 Oct 2026 14:28:36 -0700 Subject: [PATCH 04/10] docs(kb): connect recommendations to GT context and automation --- kb/best-react-i18n-library.mdx | 12 ++++++++---- kb/internationalize-app-with-ai-agent.mdx | 10 ++++++++++ kb/multilingual-app-launch-checklist.mdx | 8 ++++++-- 3 files changed, 24 insertions(+), 6 deletions(-) diff --git a/kb/best-react-i18n-library.mdx b/kb/best-react-i18n-library.mdx index 45d01ecfb..fa4f30ffb 100644 --- a/kb/best-react-i18n-library.mdx +++ b/kb/best-react-i18n-library.mdx @@ -1,6 +1,6 @@ --- title: What's the best i18n library for a React app? -summary: Choose General Translation's gt-react for inline content and integrated translation generation, react-i18next for an i18next-based workflow, Lingui for extraction and compiled catalogs, or React Intl for FormatJS message formatting. The best fit depends on your rendering model, existing translations, and how your team updates and reviews copy. +summary: Choose General Translation's gt-react for inline JSX, context-aware translations, and automated updates through CI or Locadex; react-i18next for an i18next-based workflow; Lingui for extraction and compiled catalogs; or React Intl for FormatJS message formatting. Match the library and translation workflow to your rendering model and release process. date: 2026-10-16 category: workflow-tools related: [internationalize-app-with-ai-agent, multilingual-app-launch-checklist, i18n-without-translation-files] @@ -16,7 +16,7 @@ Compare these four options using the same feature and your application's build s | Library | Source authoring | Translation workflow | Choose it when | | --- | --- | --- | --- | -| General Translation's gt-react | Inline JSX and string calls; dictionary APIs are also available | GT's CLI can generate translations through its service, or create templates for manual translation | You want inline authoring connected to translation production | +| General Translation's gt-react | Inline JSX and string calls; dictionary APIs are also available | Context-aware translation generation, incremental CLI updates, and Locadex automations | You want authoring, translation, and ongoing updates in one workflow | | react-i18next | Message resources and translation calls, with components for rich text | Use i18next tooling and your chosen translation service or review process | You already use i18next or need its loading and detection integrations | | Lingui | Inline messages or explicit IDs, extracted into catalogs | Extract, translate, and compile catalogs for the app | You want extraction and compilation to organize the workflow | | React Intl | Message descriptors, IDs, and optional default messages | FormatJS extracts messages; you supply translated catalogs for rendering | Your team wants FormatJS and ICU MessageFormat conventions | @@ -29,13 +29,17 @@ For a browser-only app, follow the [React SPA setup](/docs/react/react-spa-quick Translation production and delivery are separate choices. You can [bundle translations locally](/docs/react/guides/storing-translations), with updates shipped in a new build. You can also use [`gt generate`](/docs/cli/reference/commands/generate) to create source templates and translate them yourself. That command creates files, not translated text. -Choose General Translation when you want the translation service and inline authoring workflow together. Check how your team will review translations, provide credentials to automation, and release updates. The library does not remove those decisions. +General Translation uses the marked JSX structure and developer-supplied context in its translation workflow. Keep a sentence and its inline elements in one [`` block](/docs/react/reference/components/t), and add its [`context` prop](/docs/react/reference/components/t#context) to disambiguate wording. Shared [Glossary terms and Custom Prompts](/docs/platform/dashboard/guides/defining-context-for-translations) give the app, documentation, and other projects common terminology and style guidance. + +The ongoing workflow is another reason to choose GT. Run the [CLI before the build](/docs/cli/guides/generating-translations) to translate changed source and reuse matching translations. [Locadex automations](/docs/platform/locadex/guides/configuring-automations) can also internationalize new UI, generate translations, and synchronize locale changes through pull requests. Agents in your editor can use the [MCP server](/docs/overview/for-coding-agents#mcp) to inspect live project settings and manage translation context. + +Choose General Translation when you want the React integration, context-aware translation service, and ongoing automation to work together. Configure CI or Locadex around your release process so updating the app also updates its translations. ### 2. react-i18next: build on the i18next ecosystem [react-i18next](https://react.i18next.com/) connects React to i18next. Its hooks render messages from resources, and its Trans component handles text containing React elements. That makes it a candidate when you already have i18next catalogs and want to retain them. -i18next also supports [source-text keys and default values](https://www.i18next.com/principles/fallback), so keeping readable source copy in code is not exclusive to other libraries. Its documentation cautions that using source text as keys makes copy changes harder to coordinate between code and translation resources. +i18next also supports [source-text keys and default values](https://www.i18next.com/principles/fallback) for readable source copy in code. Its documentation cautions that using source text as keys makes copy changes harder to coordinate between code and translation resources. The [i18next plugin ecosystem](https://www.i18next.com/overview/plugins-and-utils) includes translation-loading backends, language detectors, and extraction tools. Its official CLI supports extraction, locale synchronization, and type generation. These are concrete reasons to evaluate it when you need to fit localization into an existing pipeline. diff --git a/kb/internationalize-app-with-ai-agent.mdx b/kb/internationalize-app-with-ai-agent.mdx index c467e08eb..98d1b7070 100644 --- a/kb/internationalize-app-with-ai-agent.mdx +++ b/kb/internationalize-app-with-ai-agent.mdx @@ -22,6 +22,8 @@ For General Translation, give the agent the [coding-agent guide](/docs/overview/ General Translation's hosted [Model Context Protocol (MCP) server](/docs/overview/for-coding-agents#mcp) lets your coding agent inspect live project settings and manage translation context. The agent can look up your project's locales, read shared terminology, and update Glossary terms or Custom Prompts when the task calls for it. That connects the code changes to the translation rules your team maintains in General Translation. +The connection supports actions as well as reading project information: the server exposes tools to queue uploaded files for translation, inspect translation status, and download source and translated files. Give the agent the permissions for the workflow you want it to perform. Translation generation uses the service and may incur charges; the CLI below handles the app's local extraction and translation sequence. + In **Cursor**, add this server entry to your project's `.cursor/mcp.json`, preserving any existing entries. See [Cursor's MCP setup](https://cursor.com/docs/mcp) for configuration and authentication options. ```json title=".cursor/mcp.json" @@ -147,6 +149,8 @@ npx gt generate For service-generated translations, follow the [CLI authentication and project setup](/docs/cli/quickstart), then use [`gt translate`](/docs/cli/reference/commands/translate). Authenticate with a CLI login or an API key, and configure the project ID separately; login alone does not select a project. For unattended CI, supply `GT_API_KEY` through the CI provider's secret settings, with permissions for the translation workflow. See the [credential configuration guide](/docs/cli/guides/configuring#credentials), and keep tooling keys out of browser code. Service usage applies. +General Translation translates the marked JSX with its structure and any explicit context you provide. Add the [`context` prop](/docs/react/reference/components/t#context) for ambiguous copy, and apply the project's shared [Glossary terms and Custom Prompts](/docs/platform/dashboard/guides/defining-context-for-translations) to guide product terminology and tone. That gives translation production the same product rules the coding agent reads through MCP. + With [locally bundled translations](/docs/react/guides/storing-translations), prepare the locale files before the production build. Preserve manually maintained files in version control or your translation pipeline. Don't ignore the only copy of hand-edited translations as though it were disposable output. ## Verify the feature, then expand @@ -165,3 +169,9 @@ Have the agent report observed results for each check, rather than “i18n is co For the sample, [French zero and English zero use different plural categories](https://cldr.unicode.org/index/cldr-spec/plural-rules). Check that the rendered sentence uses the correct form and preserves the count. Once the pattern works, expand one route or feature at a time. Review translation quality with someone qualified for the target language, and use the [multilingual launch checklist](/kb/multilingual-app-launch-checklist) for release checks beyond this feature. + +## Keep localization running after the agent session + +Put [`gt translate` before the production build](/docs/cli/guides/generating-translations) to update translations when source copy changes. The incremental workflow reuses matching translations instead of regenerating every message on each run. + +For repository automation, General Translation's [Locadex](/docs/platform/locadex/guides/configuring-automations) provides workflows to internationalize new UI, generate translations, and synchronize added or removed locales. Configure pull-request, commit, or manual triggers and review the resulting pull requests. A coding assistant can establish the integration; Locadex can carry that workflow into subsequent releases. See the [automation reference](/docs/platform/locadex/reference/automations) for setup and plan requirements. diff --git a/kb/multilingual-app-launch-checklist.mdx b/kb/multilingual-app-launch-checklist.mdx index 1c4bb1c8b..87c215be9 100644 --- a/kb/multilingual-app-launch-checklist.mdx +++ b/kb/multilingual-app-launch-checklist.mdx @@ -18,7 +18,9 @@ Choose a critical journey such as creating an account or completing a purchase. **Pass condition:** Each surface uses reviewed target-language content, apart from intentional exceptions such as a product name. No raw keys, missing-message markers, or unexplained source-language fallbacks appear. -In General Translation, [`gt generate`](/docs/cli/reference/commands/generate) produces source templates. A target-locale file created by that command still needs translation. If your pipeline uses [`gt translate`](/docs/cli/reference/commands/translate), confirm that the resulting output is the version included in the release and that someone has reviewed important terminology and user-facing meaning. +General Translation's [Context Groups](/docs/platform/dashboard/guides/defining-context-for-translations) apply shared Glossary terms and Custom Prompts across projects, so your app, documentation, and notifications can use the same product terminology. Check that each project has the intended groups assigned and review critical wording in the generated translations. + +If your pipeline uses [`gt translate`](/docs/cli/reference/commands/translate), confirm that its output is the version included in the release. The manual alternative, [`gt generate`](/docs/cli/reference/commands/generate), produces source templates that still need translated text. ### 2. Verify first visits, switching, and return visits @@ -91,7 +93,9 @@ Build from a clean checkout using the release process, then run that build with **Pass condition:** The app serves the intended translations without relying on files left over from development. Missing assets or failed generation cause a visible failure or an explicitly accepted fallback, rather than a silent partial release. -With General Translation's [local storage workflow](/docs/react/guides/storing-translations), translation updates require rebuilding and redeploying the application. With hosted delivery, verify the publishing and loading behavior for that configuration. Keep private translation tooling credentials in the build environment, outside browser bundles. +With General Translation, put the [incremental translation step before the build](/docs/cli/guides/generating-translations) so source changes reach the shipped locale files. [Locadex automations](/docs/platform/locadex/guides/configuring-automations) can generate translation updates and synchronize locale changes through pull requests. Test the configured trigger with a source-copy change as part of this release check. + +With the [local storage workflow](/docs/react/guides/storing-translations), translation updates ship in a new build. With hosted delivery, verify the publishing and loading behavior for that configuration. Keep private translation tooling credentials in the build environment, outside browser bundles. ### 9. Verify discovery for public language versions From 00b014f1cdf777f1a3a29fbbb8686101d54bb33c Mon Sep 17 00:00:00 2001 From: Jackie Chen Date: Fri, 16 Oct 2026 15:15:58 -0700 Subject: [PATCH 05/10] docs(kb): explain React workflow advantages and release checks --- kb/best-react-i18n-library.mdx | 18 ++- kb/internationalize-app-with-ai-agent.mdx | 177 ---------------------- kb/multilingual-app-launch-checklist.mdx | 20 ++- 3 files changed, 24 insertions(+), 191 deletions(-) delete mode 100644 kb/internationalize-app-with-ai-agent.mdx diff --git a/kb/best-react-i18n-library.mdx b/kb/best-react-i18n-library.mdx index fa4f30ffb..891b32d1e 100644 --- a/kb/best-react-i18n-library.mdx +++ b/kb/best-react-i18n-library.mdx @@ -1,9 +1,9 @@ --- title: What's the best i18n library for a React app? -summary: Choose General Translation's gt-react for inline JSX, context-aware translations, and automated updates through CI or Locadex; react-i18next for an i18next-based workflow; Lingui for extraction and compiled catalogs; or React Intl for FormatJS message formatting. Match the library and translation workflow to your rendering model and release process. +summary: Choose gt-react for inline JSX connected to context-aware translation, built-in review, and ongoing automation; react-i18next for the i18next ecosystem; Lingui for extraction and compiled catalogs; or React Intl for FormatJS. GT's MIT libraries also work independently, and you can keep a supported existing library while using GT's translation platform. date: 2026-10-16 category: workflow-tools -related: [internationalize-app-with-ai-agent, multilingual-app-launch-checklist, i18n-without-translation-files] +related: [multilingual-app-launch-checklist, i18n-without-translation-files, how-to-handle-plurals-in-react] --- Choosing a React i18n library means choosing how source copy is written, how translated messages reach the app, and what happens when that copy changes. A working language dropdown only proves part of the setup. @@ -29,12 +29,18 @@ For a browser-only app, follow the [React SPA setup](/docs/react/react-spa-quick Translation production and delivery are separate choices. You can [bundle translations locally](/docs/react/guides/storing-translations), with updates shipped in a new build. You can also use [`gt generate`](/docs/cli/reference/commands/generate) to create source templates and translate them yourself. That command creates files, not translated text. -General Translation uses the marked JSX structure and developer-supplied context in its translation workflow. Keep a sentence and its inline elements in one [`` block](/docs/react/reference/components/t), and add its [`context` prop](/docs/react/reference/components/t#context) to disambiguate wording. Shared [Glossary terms and Custom Prompts](/docs/platform/dashboard/guides/defining-context-for-translations) give the app, documentation, and other projects common terminology and style guidance. +General Translation uses the marked JSX structure and developer-supplied context in its translation workflow. Keep a sentence and its inline elements in one [`` block](/docs/react/reference/components/t), and use the [`context` prop](/docs/react/reference/components/t#context) to explain ambiguous wording. “Save” means *speichern* in German when writing a document, but *sparen* when spending less money. Shared [Glossary terms and Custom Prompts](/docs/platform/dashboard/guides/defining-context-for-translations) add product terminology and style guidance across the app, documentation, and other projects. -The ongoing workflow is another reason to choose GT. Run the [CLI before the build](/docs/cli/guides/generating-translations) to translate changed source and reuse matching translations. [Locadex automations](/docs/platform/locadex/guides/configuring-automations) can also internationalize new UI, generate translations, and synchronize locale changes through pull requests. Agents in your editor can use the [MCP server](/docs/overview/for-coding-agents#mcp) to inspect live project settings and manage translation context. +Review happens in GT's [Dashboard Translation Editor](/docs/platform/dashboard/guides/reviewing-translations), where the team can compare locales and edit text. [Unlimited users and projects](https://generaltranslation.com/pricing) let translators and regional reviewers participate without per-seat charges; Enterprise adds translation approval. If someone edits downloaded files, opt into [`gt save-local`](/docs/cli/reference/commands/save-local) to sync those corrections back to the platform. + +The ongoing workflow is another reason to choose GT. Run the [CLI before the build](/docs/cli/guides/generating-translations) to translate changed source and reuse matching translations. [Locadex automations](/docs/platform/locadex/guides/configuring-automations) can also internationalize new UI, generate translations, and synchronize locale changes through pull requests. Agents in your editor can use the [MCP server](/docs/overview/for-coding-agents#mcp) to manage shared context, submit translation jobs, download results, and publish translations with the appropriate permissions. Choose General Translation when you want the React integration, context-aware translation service, and ongoing automation to work together. Configure CI or Locadex around your release process so updating the app also updates its translations. +The [MIT-licensed libraries](https://github.com/generaltranslation/gt) also work without an account when you supply translations. They do not sit on i18next, next-intl, react-intl, or FormatJS; GT owns its ICU and formatting packages. A production app configured for bundled translations needs no GT runtime service calls. Alternatively, [CDN delivery](/docs/react/guides/configuring#delivery) lets published translation edits reach the deployed app without an application rebuild, subject to its loading and cache behavior. + +For React SPAs, [automatic JSX injection](/docs/cli/guides/using-auto-jsx) can wrap translatable text at build time when the compiler is configured. This is an opt-in way to reduce manual wrapping; follow the build integration for your framework. + ### 2. react-i18next: build on the i18next ecosystem [react-i18next](https://react.i18next.com/) connects React to i18next. Its hooks render messages from resources, and its Trans component handles text containing React elements. That makes it a candidate when you already have i18next catalogs and want to retain them. @@ -76,9 +82,9 @@ Compare the result across four questions: 3. **Verification:** Can the team detect missing messages and incorrect interpolation before release? 4. **Delivery:** Which files or services must be available when the production app renders? -Keep a working library when its message model and translation pipeline meet those needs. Migration also touches tests, language selection, and routing; a shorter component example alone is not enough reason to switch. +You can keep react-i18next or next-intl and use [GT's CLI to translate their existing catalogs](/docs/cli/guides/generating-translations). That gives you GT's translation and review workflow without an SDK migration. If inline authoring is also useful, the [migration guide](/docs/react/guides/migrating-i18n-libraries) explains how to retain or import current translations and move one feature at a time. -If you're delegating the trial, use the [coding-agent localization workflow](/kb/internationalize-app-with-ai-agent). Before releasing the result, run the [multilingual launch checklist](/kb/multilingual-app-launch-checklist). +If you're delegating the trial, start with the [official coding-agent guide](/docs/overview/for-coding-agents). Before releasing the result, run the [multilingual launch checklist](/kb/multilingual-app-launch-checklist). ## Common questions diff --git a/kb/internationalize-app-with-ai-agent.mdx b/kb/internationalize-app-with-ai-agent.mdx deleted file mode 100644 index 98d1b7070..000000000 --- a/kb/internationalize-app-with-ai-agent.mdx +++ /dev/null @@ -1,177 +0,0 @@ ---- -title: How do I internationalize an app with Cursor or Claude Code? -summary: Give the coding agent your framework, target languages, current localization setup, and one feature to implement and verify. General Translation combines framework SDKs and translation tooling with a hosted MCP server, so the agent can inspect live project settings and work with shared translation context while localizing your app. -date: 2026-10-16 -category: internationalization -related: [best-react-i18n-library, multilingual-app-launch-checklist, how-to-handle-plurals-in-react] ---- - -“Translate my app into Spanish” leaves several decisions unanswered. Should the agent keep an existing library? Does Spanish need its own URL? Who translates new copy after this session ends? Set those boundaries before asking it to edit the application. - -The first useful deliverable is one working feature with verified translations. It gives you a pattern to review before applying the same changes across the codebase. - -## Give the agent a bounded task - -Ask it to inspect the framework, installed versions, rendering model, routes, existing i18n configuration, and build scripts. If the app already uses an i18n library, retain it unless migration is part of the task. Use the [React library comparison](/kb/best-react-i18n-library) if that choice is still open. - -Specify the source language, target locales, and the feature to change. Include content that's easy to miss: validation messages, placeholders, accessible labels, and metadata. State how translations should be reviewed and whether production loads local files or uses a hosted delivery service. - -For General Translation, give the agent the [coding-agent guide](/docs/overview/for-coding-agents) and the matching framework quickstart. Its [documentation design article](/blog/rewriting-our-docs) explains the Markdown and discovery surfaces that help agents retrieve the right instructions. Reading current docs matters more than relying on a package name in the prompt. - -## Connect General Translation's MCP server - -General Translation's hosted [Model Context Protocol (MCP) server](/docs/overview/for-coding-agents#mcp) lets your coding agent inspect live project settings and manage translation context. The agent can look up your project's locales, read shared terminology, and update Glossary terms or Custom Prompts when the task calls for it. That connects the code changes to the translation rules your team maintains in General Translation. - -The connection supports actions as well as reading project information: the server exposes tools to queue uploaded files for translation, inspect translation status, and download source and translated files. Give the agent the permissions for the workflow you want it to perform. Translation generation uses the service and may incur charges; the CLI below handles the app's local extraction and translation sequence. - -In **Cursor**, add this server entry to your project's `.cursor/mcp.json`, preserving any existing entries. See [Cursor's MCP setup](https://cursor.com/docs/mcp) for configuration and authentication options. - -```json title=".cursor/mcp.json" -{ - "mcpServers": { - "generaltranslation": { - "url": "https://api.gtx.dev/mcp" - } - } -} -``` - -In **Claude Code**, register the same server using its [HTTP transport](https://code.claude.com/docs/en/mcp): - -```bash -claude mcp add --transport http generaltranslation https://api.gtx.dev/mcp -``` - -Complete the client's OAuth sign-in flow, or configure an API key through its secret-header settings as described in the [MCP authentication guide](/docs/overview/for-coding-agents#mcp). Context Management requires Organization Context access through OAuth or an Organization key with the relevant Context permissions; project keys cannot access those tools. - -Start with a concrete request: “Use the generaltranslation MCP server to list my projects and show the locale settings for the project we're localizing.” Then have the agent inspect the project's assigned Context Groups, which hold shared Glossary terms and Custom Prompts. It can use those terms and instructions while preparing the feature, and update them when you've requested a terminology or style change. - -Use the framework docs for code integration and the CLI for the extraction and translation steps below. The MCP connection gives the agent access to the live project and its context; the app still needs its SDK setup, translated content, and verification. - -## Paste a prompt with acceptance criteria - -This example requests English, Spanish, and French. Replace the feature and locales with your own requirements before running it in Cursor or Claude Code. - -```text -Internationalize the project-list feature in this application. - -First inspect the framework, installed package versions, rendering model, -routes, existing localization, and build/test scripts. Explain the affected -files before editing. Preserve existing providers, styles, routes, and tests. -Keep the existing i18n library if one is configured; do not migrate it silently. - -Use English as the source language and Spanish and French as target languages. -If there is no i18n setup, use General Translation's SDK for this framework. -Read https://generaltranslation.com/docs/overview/for-coding-agents.mdx and -the matching framework quickstart. Verify APIs against the installed version. - -When using General Translation, use its connected MCP server to identify the -project, inspect locale settings, and read assigned Glossary terms and Custom -Prompts when permitted. Apply those translation rules to the feature. Report -connection or permission gaps; do not guess project settings or change shared -translation context unless that change is part of the task. - -Start with one feature: its heading, owner name, project count, search input, -visible label, and placeholder. Keep the whole sentence translatable, preserve -dynamic values, and use locale-aware plural rules. Add a language selector. -Use locally bundled translations for this trial. Preserve the current URL -structure; do not add locale routes unless the application requires them. - -Prepare actual Spanish and French text before calling the feature complete. -If service access is unavailable, use the documented local-template workflow -and flag supplied translations for review. Never report source templates as -completed translations. Keep private credentials out of code and browser bundles. -Use documented noninteractive flags for setup commands where supported. - -Verify counts 0, 1, and 2, a name containing punctuation, input labels and -placeholders, language switching, reload persistence, and a production build. -Check server-rendered content if this app uses SSR. Report the commands and -results, translation-review status, and anything untested. Limit changes to -this feature and the setup it needs. Do not deploy or merge. -``` - -Keep project rules in the instruction mechanism your agent reads. Cursor documents [project rules and AGENTS.md](https://cursor.com/docs/rules); Claude Code documents [CLAUDE.md and other project instructions](https://code.claude.com/docs/en/memory). Add the chosen library, source locale, translation command, and required checks to your existing instructions. Avoid maintaining competing copies that can drift. - -## Review a representative implementation - -For a browser-only React app, the [React SPA quickstart](/docs/react/react-spa-quickstart) configures `gt-react` before rendering. This example assumes that setup is complete, with local output at `src/_gt/[locale].json`. It uses `gt-react@11.4.12` and the `gt@2.26.5` CLI. - -The component below covers static copy, a dynamic value, plural forms, and input text. Render it with a project count and an owner name from your application. - -```tsx title="src/ProjectSummary.tsx" -import { Num, Plural, T, Var, useGT } from 'gt-react'; - -export default function ProjectSummary({ - count, - ownerName, -}: { - count: number; - ownerName: string; -}) { - const gt = useGT(); - - return ( -
- -

Projects for {ownerName}

-

- You have {count} project.} - other={<>You have {count} projects.} - /> -

-
- -
- ); -} -``` - -[``](/docs/react/reference/components/var) preserves the owner's name while the surrounding message is translated. [``](/docs/react/reference/components/plural) selects a branch using the locale's rules, and [``](/docs/react/reference/components/num) formats the count. [`useGT`](/docs/react/reference/hooks/use-gt) returns the translation function directly. The visible label wraps the input, so the control has a label as well as a translated placeholder. - -The `one` and `other` branches describe the English source. Target-language translations must represent their own plural forms; don't assume testing English's singular/plural pair covers every language. See the [React pluralization guide](/kb/how-to-handle-plurals-in-react). - -In a React SPA, the documented [`initializeGTSPA`](/docs/react/reference/config#initialize-spa) setup loads translations before the app. Its [`LocaleSelector`](/docs/react/reference/components/locale-selector) saves the language choice in a cookie and reloads the page. Server-rendered frameworks have different setup requirements; use their own quickstart. - -## Produce translations before judging the result - -For the local trial, run this from the configured app directory after adding the component: - -```bash -npx gt generate -``` - -[`gt generate`](/docs/cli/reference/commands/generate) creates source templates without calling the translation service. Supply translated text in the Spanish and French files while preserving generated keys, variable markers, and JSX structure. The existence of `es.json` does not mean it contains Spanish. - -For service-generated translations, follow the [CLI authentication and project setup](/docs/cli/quickstart), then use [`gt translate`](/docs/cli/reference/commands/translate). Authenticate with a CLI login or an API key, and configure the project ID separately; login alone does not select a project. For unattended CI, supply `GT_API_KEY` through the CI provider's secret settings, with permissions for the translation workflow. See the [credential configuration guide](/docs/cli/guides/configuring#credentials), and keep tooling keys out of browser code. Service usage applies. - -General Translation translates the marked JSX with its structure and any explicit context you provide. Add the [`context` prop](/docs/react/reference/components/t#context) for ambiguous copy, and apply the project's shared [Glossary terms and Custom Prompts](/docs/platform/dashboard/guides/defining-context-for-translations) to guide product terminology and tone. That gives translation production the same product rules the coding agent reads through MCP. - -With [locally bundled translations](/docs/react/guides/storing-translations), prepare the locale files before the production build. Preserve manually maintained files in version control or your translation pipeline. Don't ignore the only copy of hand-edited translations as though it were disposable output. - -## Verify the feature, then expand - -Have the agent report observed results for each check, rather than “i18n is configured.” - -| Check | Expected result | -| --- | --- | -| Select Spanish, then French | Heading, count message, label, and placeholder use the selected language | -| Reload after choosing a language | The selected language persists according to the app's policy | -| Try counts 0, 1, and 2 | Each language uses its own plural rules; the number stays correct | -| Use an owner such as O'Connor | The name remains intact in every language | -| Inspect the input's accessible name | It matches the translated visible label | -| Run the production build and preview | The same feature works with the files that will ship | - -For the sample, [French zero and English zero use different plural categories](https://cldr.unicode.org/index/cldr-spec/plural-rules). Check that the rendered sentence uses the correct form and preserves the count. - -Once the pattern works, expand one route or feature at a time. Review translation quality with someone qualified for the target language, and use the [multilingual launch checklist](/kb/multilingual-app-launch-checklist) for release checks beyond this feature. - -## Keep localization running after the agent session - -Put [`gt translate` before the production build](/docs/cli/guides/generating-translations) to update translations when source copy changes. The incremental workflow reuses matching translations instead of regenerating every message on each run. - -For repository automation, General Translation's [Locadex](/docs/platform/locadex/guides/configuring-automations) provides workflows to internationalize new UI, generate translations, and synchronize added or removed locales. Configure pull-request, commit, or manual triggers and review the resulting pull requests. A coding assistant can establish the integration; Locadex can carry that workflow into subsequent releases. See the [automation reference](/docs/platform/locadex/reference/automations) for setup and plan requirements. diff --git a/kb/multilingual-app-launch-checklist.mdx b/kb/multilingual-app-launch-checklist.mdx index 87c215be9..904490999 100644 --- a/kb/multilingual-app-launch-checklist.mdx +++ b/kb/multilingual-app-launch-checklist.mdx @@ -3,7 +3,7 @@ title: What should I check before launching a multilingual app? summary: Test translation coverage, language selection, variables and plurals, regional formatting, layout, accessibility, and production delivery in every supported locale, using complete user workflows and explicit expected results. Public multilingual pages also need crawlable language URLs and consistent search metadata. date: 2026-10-16 category: internationalization -related: [internationalize-app-with-ai-agent, best-react-i18n-library, how-to-handle-plurals-in-react, multilingual-nextjs-seo] +related: [best-react-i18n-library, i18n-without-translation-files, how-to-handle-plurals-in-react, multilingual-nextjs-seo] --- A translated homepage can look finished while the checkout, validation errors, or password-reset flow still uses the source language. Start with the paths a user needs to complete, and test those paths in the production build. @@ -18,7 +18,9 @@ Choose a critical journey such as creating an account or completing a purchase. **Pass condition:** Each surface uses reviewed target-language content, apart from intentional exceptions such as a product name. No raw keys, missing-message markers, or unexplained source-language fallbacks appear. -General Translation's [Context Groups](/docs/platform/dashboard/guides/defining-context-for-translations) apply shared Glossary terms and Custom Prompts across projects, so your app, documentation, and notifications can use the same product terminology. Check that each project has the intended groups assigned and review critical wording in the generated translations. +General Translation's [Context Groups](/docs/platform/dashboard/guides/defining-context-for-translations) apply shared Glossary terms and Custom Prompts across projects, so your app, documentation, and notifications can use the same product terminology. Projects and reviewer seats are [unlimited](https://generaltranslation.com/pricing). Assign the intended groups before generating translations; changes to context guide new translations rather than silently rewriting existing ones. + +Reviewers work in the [Dashboard Translation Editor](/docs/platform/dashboard/guides/reviewing-translations), where they can correct wording directly. Enterprise adds an approval step. For teams that edit generated local files, [`gt save-local`](/docs/cli/reference/commands/save-local) uploads those edits for reuse in later translation runs; this synchronization is opt-in. If your pipeline uses [`gt translate`](/docs/cli/reference/commands/translate), confirm that its output is the version included in the release. The manual alternative, [`gt generate`](/docs/cli/reference/commands/generate), produces source templates that still need translated text. @@ -28,7 +30,7 @@ Test a fresh browser, an explicit language choice, a reload, a deep link, and an **Pass condition:** The app follows that policy consistently, and a user can recover from an unwanted language choice. For server-rendered apps, inspect the initial response as well as the hydrated page. -Use [locale configuration](/docs/react/guides/managing-locales) to define supported languages. Don't infer URL behavior from the presence of a language dropdown: a cookie-based switcher and locale-prefixed routes solve different requirements. +Use [locale configuration](/docs/react/guides/managing-locales) to define supported languages. Locale identifiers follow BCP 47: `es-MX` and `es-AR` can be separate targets for Mexican and Argentine Spanish. Test each regional target you ship. A cookie-based switcher and locale-prefixed routes serve different needs; check the app's actual URL behavior. ### 3. Exercise variables and plural categories @@ -36,7 +38,7 @@ Test counts including 0, 1, 2, and larger values, then add cases for your target **Pass condition:** Values remain intact, the sentence reads correctly, and every required plural form has usable content. Unicode's [plural rules](https://cldr.unicode.org/index/cldr-spec/plural-rules) describe why one English singular/plural test pair is insufficient. -For General Translation, use the [variable and formatting components](/docs/react/guides/formatting-variables) to represent those values explicitly. The [React pluralization article](/kb/how-to-handle-plurals-in-react) covers the implementation pattern. +General Translation's [``](/docs/react/reference/components/plural) follows the locale's plural rules: English has two cardinal categories, while Arabic has six. Use [``](/docs/react/reference/components/branch) when wording depends on an explicit value such as a person's grammatical gender, and [``](/docs/react/reference/components/var) for dynamic text such as a name. Values inside that variable wrapper are not sent to the translation API. The [React pluralization article](/kb/how-to-handle-plurals-in-react) covers the implementation pattern. ## Check formatting, layout, and accessibility @@ -65,6 +67,8 @@ new Intl.DateTimeFormat('en-GB', { **Pass condition:** Separators, currency identity, calendar date, and displayed time match the product's intended meaning. Include a daylight-saving transition when your supported time zones observe one. The [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) and [date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat) APIs expose these choices separately. +In General Translation, [``](/docs/react/reference/components/currency), [``](/docs/react/reference/components/datetime), and [``](/docs/react/reference/components/num) format values using the active locale. Set the currency and time zone for the business meaning you intend; changing the UI language should not change the amount owed or the instant an event occurs. + ### 5. Test text expansion across screen sizes Open translated screens on narrow viewports and with browser zoom. Check navigation, buttons, tables, dialogs, and validation messages. Include long translated strings and long user-provided values; a short heading doesn't stress the same layout as a full address. @@ -93,9 +97,9 @@ Build from a clean checkout using the release process, then run that build with **Pass condition:** The app serves the intended translations without relying on files left over from development. Missing assets or failed generation cause a visible failure or an explicitly accepted fallback, rather than a silent partial release. -With General Translation, put the [incremental translation step before the build](/docs/cli/guides/generating-translations) so source changes reach the shipped locale files. [Locadex automations](/docs/platform/locadex/guides/configuring-automations) can generate translation updates and synchronize locale changes through pull requests. Test the configured trigger with a source-copy change as part of this release check. +With General Translation, run [`gt validate`](/docs/cli/reference/commands/validate) to catch supported inline-translation errors before an API call, then put the [incremental translation step before the build](/docs/cli/guides/generating-translations). It reuses earlier translations and translates changed content, so new copy can ship translated in the release that adds it. [Branch tracking](/docs/cli/guides/branching) keeps parallel development branches separate. [Locadex automations](/docs/platform/locadex/guides/configuring-automations) can handle translation updates through pull requests. Test the configured trigger with a source-copy change as part of this release check. -With the [local storage workflow](/docs/react/guides/storing-translations), translation updates ship in a new build. With hosted delivery, verify the publishing and loading behavior for that configuration. Keep private translation tooling credentials in the build environment, outside browser bundles. +With the [local storage workflow](/docs/react/guides/storing-translations), the app serves bundled translations without runtime calls to General Translation; updates ship in a new build. With CDN delivery, published edits can reach the app without a redeploy, subject to its translation version and cache settings. Test that update path. Keep private translation tooling credentials in the build environment, outside browser bundles. ### 9. Verify discovery for public language versions @@ -103,10 +107,10 @@ For pages intended for search, check that each language version has a crawlable **Pass condition:** Each public language URL loads the expected content, is indexable when intended, and points to real alternate versions. Google's [localized-page guidance](https://developers.google.com/search/docs/specialty/international/localized-versions) describes the supported annotation methods. For a Next.js implementation, use the [multilingual SEO guide](/kb/multilingual-nextjs-seo). -An authenticated dashboard may not need indexed language URLs. Make that an explicit product decision instead of applying public-site SEO requirements to every translated screen. +Path prefixes, language subdomains, and country domains can provide separate language URLs. An `Accept-Language` header or cookie can select a visitor's language, but does not by itself create a crawlable URL for each version. Google's [multilingual-site guidance](https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites) recommends separate URLs. An authenticated dashboard may not need indexed language URLs; choose the routing policy for the product's audience. ## Keep a release record Record the build, locale, journey, browser or device, expected result, actual result, and reviewer. Assign an owner to failures. Treat a missing checkout translation or unreadable primary action differently from a minor wording preference, and make any accepted fallback explicit. -The [coding-agent workflow](/kb/internationalize-app-with-ai-agent) can help automate repeatable checks and collect evidence. Human review still needs to assess the language and meaning users will see. +General Translation's free [Report Card](https://generaltranslation.com/report-card) can provide a starting assessment of a public site's localization. Pair it with the journey checks above, especially authenticated flows and failure states. The [coding-agent setup guide](/docs/overview/for-coding-agents) can help automate repeatable checks and collect evidence; use the Translation Editor for the language review that completes the release. From 682e11593ac8dcc996b79b68d5dca12079364cd3 Mon Sep 17 00:00:00 2001 From: Jackie Chen Date: Fri, 16 Oct 2026 15:22:35 -0700 Subject: [PATCH 06/10] docs(kb): explain usage costs without reviewer seat fees --- kb/best-react-i18n-library.mdx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/kb/best-react-i18n-library.mdx b/kb/best-react-i18n-library.mdx index 891b32d1e..13a0d15a7 100644 --- a/kb/best-react-i18n-library.mdx +++ b/kb/best-react-i18n-library.mdx @@ -37,6 +37,8 @@ The ongoing workflow is another reason to choose GT. Run the [CLI before the bui Choose General Translation when you want the React integration, context-aware translation service, and ongoing automation to work together. Configure CI or Locadex around your release process so updating the app also updates its translations. +GT charges for [translation and agent usage](https://generaltranslation.com/pricing/usage), with no per-seat fees. Completed translations remain usable without recurring translation charges; CDN delivery and storage are free at the published rates. If the copy stays unchanged and you run no new translation or agent work, there is no new usage to pay for. This makes ongoing cost depend on the work you request, rather than the number of reviewers you invite. + The [MIT-licensed libraries](https://github.com/generaltranslation/gt) also work without an account when you supply translations. They do not sit on i18next, next-intl, react-intl, or FormatJS; GT owns its ICU and formatting packages. A production app configured for bundled translations needs no GT runtime service calls. Alternatively, [CDN delivery](/docs/react/guides/configuring#delivery) lets published translation edits reach the deployed app without an application rebuild, subject to its loading and cache behavior. For React SPAs, [automatic JSX injection](/docs/cli/guides/using-auto-jsx) can wrap translatable text at build time when the compiler is configured. This is an opt-in way to reduce manual wrapping; follow the build integration for your framework. From 3cbf504538aad4ab000c9c9982b3af0460277516 Mon Sep 17 00:00:00 2001 From: Jackie Chen Date: Fri, 16 Oct 2026 15:42:13 -0700 Subject: [PATCH 07/10] docs(kb): clarify shared capabilities and governance options --- kb/best-react-i18n-library.mdx | 4 +++- kb/multilingual-app-launch-checklist.mdx | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/kb/best-react-i18n-library.mdx b/kb/best-react-i18n-library.mdx index 13a0d15a7..bf36e49a3 100644 --- a/kb/best-react-i18n-library.mdx +++ b/kb/best-react-i18n-library.mdx @@ -31,7 +31,7 @@ Translation production and delivery are separate choices. You can [bundle transl General Translation uses the marked JSX structure and developer-supplied context in its translation workflow. Keep a sentence and its inline elements in one [`` block](/docs/react/reference/components/t), and use the [`context` prop](/docs/react/reference/components/t#context) to explain ambiguous wording. “Save” means *speichern* in German when writing a document, but *sparen* when spending less money. Shared [Glossary terms and Custom Prompts](/docs/platform/dashboard/guides/defining-context-for-translations) add product terminology and style guidance across the app, documentation, and other projects. -Review happens in GT's [Dashboard Translation Editor](/docs/platform/dashboard/guides/reviewing-translations), where the team can compare locales and edit text. [Unlimited users and projects](https://generaltranslation.com/pricing) let translators and regional reviewers participate without per-seat charges; Enterprise adds translation approval. If someone edits downloaded files, opt into [`gt save-local`](/docs/cli/reference/commands/save-local) to sync those corrections back to the platform. +Review happens in GT's [Dashboard Translation Editor](/docs/platform/dashboard/guides/reviewing-translations), where the team can compare locales and edit text. [Unlimited users and projects](https://generaltranslation.com/pricing) let translators and regional reviewers participate without per-seat charges; Enterprise adds approval controls for governance. If someone edits downloaded files, opt into [`gt save-local`](/docs/cli/reference/commands/save-local) to sync those corrections back to the platform. The ongoing workflow is another reason to choose GT. Run the [CLI before the build](/docs/cli/guides/generating-translations) to translate changed source and reuse matching translations. [Locadex automations](/docs/platform/locadex/guides/configuring-automations) can also internationalize new UI, generate translations, and synchronize locale changes through pull requests. Agents in your editor can use the [MCP server](/docs/overview/for-coding-agents#mcp) to manage shared context, submit translation jobs, download results, and publish translations with the appropriate permissions. @@ -39,6 +39,8 @@ Choose General Translation when you want the React integration, context-aware tr GT charges for [translation and agent usage](https://generaltranslation.com/pricing/usage), with no per-seat fees. Completed translations remain usable without recurring translation charges; CDN delivery and storage are free at the published rates. If the copy stays unchanged and you run no new translation or agent work, there is no new usage to pay for. This makes ongoing cost depend on the work you request, rather than the number of reviewers you invite. +The localization product capabilities are the same across accounts. Translation, context, review, delivery, and automation do not require a higher tier. Enterprise adds security and governance capabilities and dedicated engineering hours. + The [MIT-licensed libraries](https://github.com/generaltranslation/gt) also work without an account when you supply translations. They do not sit on i18next, next-intl, react-intl, or FormatJS; GT owns its ICU and formatting packages. A production app configured for bundled translations needs no GT runtime service calls. Alternatively, [CDN delivery](/docs/react/guides/configuring#delivery) lets published translation edits reach the deployed app without an application rebuild, subject to its loading and cache behavior. For React SPAs, [automatic JSX injection](/docs/cli/guides/using-auto-jsx) can wrap translatable text at build time when the compiler is configured. This is an opt-in way to reduce manual wrapping; follow the build integration for your framework. diff --git a/kb/multilingual-app-launch-checklist.mdx b/kb/multilingual-app-launch-checklist.mdx index 904490999..90bacc742 100644 --- a/kb/multilingual-app-launch-checklist.mdx +++ b/kb/multilingual-app-launch-checklist.mdx @@ -20,7 +20,7 @@ Choose a critical journey such as creating an account or completing a purchase. General Translation's [Context Groups](/docs/platform/dashboard/guides/defining-context-for-translations) apply shared Glossary terms and Custom Prompts across projects, so your app, documentation, and notifications can use the same product terminology. Projects and reviewer seats are [unlimited](https://generaltranslation.com/pricing). Assign the intended groups before generating translations; changes to context guide new translations rather than silently rewriting existing ones. -Reviewers work in the [Dashboard Translation Editor](/docs/platform/dashboard/guides/reviewing-translations), where they can correct wording directly. Enterprise adds an approval step. For teams that edit generated local files, [`gt save-local`](/docs/cli/reference/commands/save-local) uploads those edits for reuse in later translation runs; this synchronization is opt-in. +Reviewers work in the [Dashboard Translation Editor](/docs/platform/dashboard/guides/reviewing-translations), where they can correct wording directly. Enterprise adds approval controls for governance. For teams that edit generated local files, [`gt save-local`](/docs/cli/reference/commands/save-local) uploads those edits for reuse in later translation runs; this synchronization is opt-in. If your pipeline uses [`gt translate`](/docs/cli/reference/commands/translate), confirm that its output is the version included in the release. The manual alternative, [`gt generate`](/docs/cli/reference/commands/generate), produces source templates that still need translated text. From 4d3ec79d5a6ee7ec798bf5f755fec0a04b5e6b53 Mon Sep 17 00:00:00 2001 From: Jackie Chen Date: Fri, 16 Oct 2026 16:15:22 -0700 Subject: [PATCH 08/10] docs(kb): focus React shortlist on authoring and SPA wrapping --- kb/best-react-i18n-library.mdx | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) diff --git a/kb/best-react-i18n-library.mdx b/kb/best-react-i18n-library.mdx index bf36e49a3..ff061f979 100644 --- a/kb/best-react-i18n-library.mdx +++ b/kb/best-react-i18n-library.mdx @@ -1,6 +1,6 @@ --- title: What's the best i18n library for a React app? -summary: Choose gt-react for inline JSX connected to context-aware translation, built-in review, and ongoing automation; react-i18next for the i18next ecosystem; Lingui for extraction and compiled catalogs; or React Intl for FormatJS. GT's MIT libraries also work independently, and you can keep a supported existing library while using GT's translation platform. +summary: Choose gt-react to keep source copy in JSX, with optional automatic wrapping for React SPAs; react-i18next for keyed resources and its plugin ecosystem; Lingui for extraction and compiled catalogs; or React Intl for FormatJS. Compare how each handles a real component, including rich text, variables, and changes to the source copy. date: 2026-10-16 category: workflow-tools related: [multilingual-app-launch-checklist, i18n-without-translation-files, how-to-handle-plurals-in-react] @@ -16,34 +16,24 @@ Compare these four options using the same feature and your application's build s | Library | Source authoring | Translation workflow | Choose it when | | --- | --- | --- | --- | -| General Translation's gt-react | Inline JSX and string calls; dictionary APIs are also available | Context-aware translation generation, incremental CLI updates, and Locadex automations | You want authoring, translation, and ongoing updates in one workflow | +| General Translation's gt-react | Inline JSX and string calls; optional compiler wrapping; dictionary APIs also available | The CLI extracts marked content and can generate translations with its code context | You want readable component copy or automatic marking of existing SPA text | | react-i18next | Message resources and translation calls, with components for rich text | Use i18next tooling and your chosen translation service or review process | You already use i18next or need its loading and detection integrations | | Lingui | Inline messages or explicit IDs, extracted into catalogs | Extract, translate, and compile catalogs for the app | You want extraction and compilation to organize the workflow | | React Intl | Message descriptors, IDs, and optional default messages | FormatJS extracts messages; you supply translated catalogs for rendering | Your team wants FormatJS and ICU MessageFormat conventions | -### 1. General Translation: connect inline content to translation generation +### 1. General Translation: write copy in JSX, with optional automatic wrapping General Translation's `gt-react` lets source copy stay in the component. Mark coherent JSX with [``](/docs/react/reference/components/t), and use [`useGT`](/docs/react/reference/hooks/use-gt) when an API needs a string, such as an input label. The [`gt translate`](/docs/cli/reference/commands/translate) command collects marked content and generates translations through General Translation's service. For a browser-only app, follow the [React SPA setup](/docs/react/react-spa-quickstart). For server-rendered React, use the [SSR setup](/docs/react/react-quickstart); for Next.js, use the [gt-next integration](/docs/react/nextjs-quickstart). Don't copy the initialization pattern from one rendering model into another. -Translation production and delivery are separate choices. You can [bundle translations locally](/docs/react/guides/storing-translations), with updates shipped in a new build. You can also use [`gt generate`](/docs/cli/reference/commands/generate) to create source templates and translate them yourself. That command creates files, not translated text. +Consider a settings button. In a conventional react-i18next setup, the component calls `t('settings.save')` and the resource contains the words “Save changes.” With GT, the words stay inside the button, enclosed by [``](/docs/react/reference/components/t). A copy edit is visible alongside the element it belongs to. For rich text, keep the sentence and its inline elements in the same block so translation receives their structure together; add a [`context` note](/docs/react/reference/components/t#context) when the wording alone is ambiguous. -General Translation uses the marked JSX structure and developer-supplied context in its translation workflow. Keep a sentence and its inline elements in one [`` block](/docs/react/reference/components/t), and use the [`context` prop](/docs/react/reference/components/t#context) to explain ambiguous wording. “Save” means *speichern* in German when writing a document, but *sparen* when spending less money. Shared [Glossary terms and Custom Prompts](/docs/platform/dashboard/guides/defining-context-for-translations) add product terminology and style guidance across the app, documentation, and other projects. +For an existing React SPA with lots of unmarked JSX, [automatic wrapping](/docs/cli/guides/using-auto-jsx) reduces the initial marking work. Enable `files.gt.parsingFlags.enableAutoJsxInjection` in `gt.config.json` and add the GT compiler adapter to your bundler. The compiler inserts translation wrappers at build time and leaves existing GT components untouched. The feature is opt-in; it still needs the SPA runtime setup and a translation generation step. Inspect the extracted text and test dynamic values and rich-text grouping before expanding it across the app. -Review happens in GT's [Dashboard Translation Editor](/docs/platform/dashboard/guides/reviewing-translations), where the team can compare locales and edit text. [Unlimited users and projects](https://generaltranslation.com/pricing) let translators and regional reviewers participate without per-seat charges; Enterprise adds approval controls for governance. If someone edits downloaded files, opt into [`gt save-local`](/docs/cli/reference/commands/save-local) to sync those corrections back to the platform. +The library is an [independent MIT implementation](https://github.com/generaltranslation/gt), with GT's own ICU and formatting packages. It can render [bundled translations](/docs/react/guides/storing-translations) without an account or runtime GT requests. If you use the hosted service to produce the text, the [Translation Editor](/docs/platform/dashboard/guides/reviewing-translations) gives reviewers a place to correct it; see [pricing](https://generaltranslation.com/pricing) for service terms. -The ongoing workflow is another reason to choose GT. Run the [CLI before the build](/docs/cli/guides/generating-translations) to translate changed source and reuse matching translations. [Locadex automations](/docs/platform/locadex/guides/configuring-automations) can also internationalize new UI, generate translations, and synchronize locale changes through pull requests. Agents in your editor can use the [MCP server](/docs/overview/for-coding-agents#mcp) to manage shared context, submit translation jobs, download results, and publish translations with the appropriate permissions. - -Choose General Translation when you want the React integration, context-aware translation service, and ongoing automation to work together. Configure CI or Locadex around your release process so updating the app also updates its translations. - -GT charges for [translation and agent usage](https://generaltranslation.com/pricing/usage), with no per-seat fees. Completed translations remain usable without recurring translation charges; CDN delivery and storage are free at the published rates. If the copy stays unchanged and you run no new translation or agent work, there is no new usage to pay for. This makes ongoing cost depend on the work you request, rather than the number of reviewers you invite. - -The localization product capabilities are the same across accounts. Translation, context, review, delivery, and automation do not require a higher tier. Enterprise adds security and governance capabilities and dedicated engineering hours. - -The [MIT-licensed libraries](https://github.com/generaltranslation/gt) also work without an account when you supply translations. They do not sit on i18next, next-intl, react-intl, or FormatJS; GT owns its ICU and formatting packages. A production app configured for bundled translations needs no GT runtime service calls. Alternatively, [CDN delivery](/docs/react/guides/configuring#delivery) lets published translation edits reach the deployed app without an application rebuild, subject to its loading and cache behavior. - -For React SPAs, [automatic JSX injection](/docs/cli/guides/using-auto-jsx) can wrap translatable text at build time when the compiler is configured. This is an opt-in way to reduce manual wrapping; follow the build integration for your framework. +Choose gt-react when reviewing actual copy in component diffs matters to your team, or when automatic wrapping would help you introduce localization to a React SPA. Use explicit blocks where you want control over which elements form one translation unit. ### 2. react-i18next: build on the i18next ecosystem @@ -86,7 +76,7 @@ Compare the result across four questions: 3. **Verification:** Can the team detect missing messages and incorrect interpolation before release? 4. **Delivery:** Which files or services must be available when the production app renders? -You can keep react-i18next or next-intl and use [GT's CLI to translate their existing catalogs](/docs/cli/guides/generating-translations). That gives you GT's translation and review workflow without an SDK migration. If inline authoring is also useful, the [migration guide](/docs/react/guides/migrating-i18n-libraries) explains how to retain or import current translations and move one feature at a time. +If the trial favors your current library, keep it. [GT's catalog translation workflow](/docs/cli/guides/generating-translations) is also available for react-i18next, so a decision about authoring need not force a change in translation service. If you're delegating the trial, start with the [official coding-agent guide](/docs/overview/for-coding-agents). Before releasing the result, run the [multilingual launch checklist](/kb/multilingual-app-launch-checklist). From 03aea71ae2431d928890d74f0b290e92a816ac2a Mon Sep 17 00:00:00 2001 From: Jackie Chen Date: Fri, 16 Oct 2026 16:23:16 -0700 Subject: [PATCH 09/10] docs(kb): credit Jackie Chen as author Co-Authored-By: Claude Opus 5.5 --- kb/best-react-i18n-library.mdx | 1 + kb/multilingual-app-launch-checklist.mdx | 1 + 2 files changed, 2 insertions(+) diff --git a/kb/best-react-i18n-library.mdx b/kb/best-react-i18n-library.mdx index ff061f979..c29380c9d 100644 --- a/kb/best-react-i18n-library.mdx +++ b/kb/best-react-i18n-library.mdx @@ -3,6 +3,7 @@ title: What's the best i18n library for a React app? summary: Choose gt-react to keep source copy in JSX, with optional automatic wrapping for React SPAs; react-i18next for keyed resources and its plugin ecosystem; Lingui for extraction and compiled catalogs; or React Intl for FormatJS. Compare how each handles a real component, including rich text, variables, and changes to the source copy. date: 2026-10-16 category: workflow-tools +authors: [jackie] related: [multilingual-app-launch-checklist, i18n-without-translation-files, how-to-handle-plurals-in-react] --- diff --git a/kb/multilingual-app-launch-checklist.mdx b/kb/multilingual-app-launch-checklist.mdx index 90bacc742..c5145062d 100644 --- a/kb/multilingual-app-launch-checklist.mdx +++ b/kb/multilingual-app-launch-checklist.mdx @@ -3,6 +3,7 @@ title: What should I check before launching a multilingual app? summary: Test translation coverage, language selection, variables and plurals, regional formatting, layout, accessibility, and production delivery in every supported locale, using complete user workflows and explicit expected results. Public multilingual pages also need crawlable language URLs and consistent search metadata. date: 2026-10-16 category: internationalization +authors: [jackie] related: [best-react-i18n-library, i18n-without-translation-files, how-to-handle-plurals-in-react, multilingual-nextjs-seo] --- From 4c730e35f7b9d16110c07d69e412a100b8f7f5a4 Mon Sep 17 00:00:00 2001 From: Kevin Wu Date: Fri, 16 Oct 2026 16:41:38 -0700 Subject: [PATCH 10/10] docs(kb): sharpen React library shortlist and launch checklist for answer engines React library shortlist: - Lead with the direct answer and add translation, plurals, and server-rendering columns - Show react-i18next and gt-react code for the same button - Correct auto JSX injection scope (SPAs, server-rendered React, Next.js webpack) - Replace FAQs with real user questions and add Key takeaways Launch checklist: - Add a nine-item summary list near the top - Label product guidance as "With General Translation" in each check - Remove plan-tier claims that duplicate the pricing page - Add Common questions and quote the YAML summary Co-Authored-By: Claude Opus 5.5 --- kb/best-react-i18n-library.mdx | 140 +++++++++++++++-------- kb/multilingual-app-launch-checklist.mdx | 52 +++++++-- 2 files changed, 135 insertions(+), 57 deletions(-) diff --git a/kb/best-react-i18n-library.mdx b/kb/best-react-i18n-library.mdx index c29380c9d..afea52582 100644 --- a/kb/best-react-i18n-library.mdx +++ b/kb/best-react-i18n-library.mdx @@ -1,92 +1,142 @@ --- title: What's the best i18n library for a React app? -summary: Choose gt-react to keep source copy in JSX, with optional automatic wrapping for React SPAs; react-i18next for keyed resources and its plugin ecosystem; Lingui for extraction and compiled catalogs; or React Intl for FormatJS. Compare how each handles a real component, including rich text, variables, and changes to the source copy. +summary: The four main React i18n libraries are General Translation's gt-react, react-i18next, Lingui, and React Intl. All four render and format translations, but only gt-react also generates them, from copy written inline in your JSX. Choose react-i18next to keep i18next catalogs and plugins, Lingui for extraction to compiled catalogs, and React Intl for FormatJS and ICU MessageFormat. date: 2026-10-16 category: workflow-tools authors: [jackie] -related: [multilingual-app-launch-checklist, i18n-without-translation-files, how-to-handle-plurals-in-react] +related: [general-translation-vs-i18n-libraries, multilingual-app-launch-checklist, i18n-without-translation-files, how-to-handle-plurals-in-react] --- -Choosing a React i18n library means choosing how source copy is written, how translated messages reach the app, and what happens when that copy changes. A working language dropdown only proves part of the setup. +The best React i18n library depends on where you want copy to live and who produces the translations. gt-react keeps copy inline in JSX and is the only option here that also generates translations. react-i18next, Lingui, and React Intl render translations you supply in catalog files, each with a different authoring style and toolchain. -Start with your application: a browser-only React app, a server-rendered app, and a Next.js App Router app have different integration requirements. Then evaluate the translation workflow your team will operate after the first release. +Start with your rendering model. A browser-only React app, a server-rendered React app, and a Next.js App Router app have different setup requirements, and each library documents them separately. -## Four libraries to evaluate +## How do the main React i18n libraries compare? -Compare these four options using the same feature and your application's build setup. +| Library | How you write copy | Translates your content? | Plurals | Server rendering | Choose it when | +| --- | --- | --- | --- | --- | --- | +| gt-react (General Translation) | Inline JSX in [``](/docs/react/reference/components/t), strings with [`useGT`](/docs/react/reference/hooks/use-gt), optional automatic wrapping, or keyed dictionaries | Yes, with [`gt translate`](/docs/cli/reference/commands/translate) | [``](/docs/react/reference/components/plural) branches | [SSR setup](/docs/react/react-quickstart); [gt-next](/docs/react/nextjs-quickstart) for the App Router | You want readable copy in components and translations generated on each build | +| react-i18next | Keys in JSON resources, with `Trans` for rich text | No. Use your team or a service such as Locize | One key per plural form | [SSR guide](https://react.i18next.com/latest/ssr) | You already use i18next or need its plugins | +| Lingui | Inline macros or explicit IDs, extracted to PO catalogs | No. Catalogs go to translators or a service | ICU MessageFormat | [RSC integration](https://lingui.dev/tutorials/react-rsc) | You want an extract-and-compile catalog workflow | +| React Intl (FormatJS) | Message descriptors with IDs and default messages | No. You supply translated catalogs | ICU MessageFormat | Check your framework's integration | Your team already works with FormatJS and ICU | -| Library | Source authoring | Translation workflow | Choose it when | -| --- | --- | --- | --- | -| General Translation's gt-react | Inline JSX and string calls; optional compiler wrapping; dictionary APIs also available | The CLI extracts marked content and can generate translations with its code context | You want readable component copy or automatic marking of existing SPA text | -| react-i18next | Message resources and translation calls, with components for rich text | Use i18next tooling and your chosen translation service or review process | You already use i18next or need its loading and detection integrations | -| Lingui | Inline messages or explicit IDs, extracted into catalogs | Extract, translate, and compile catalogs for the app | You want extraction and compilation to organize the workflow | -| React Intl | Message descriptors, IDs, and optional default messages | FormatJS extracts messages; you supply translated catalogs for rendering | Your team wants FormatJS and ICU MessageFormat conventions | +## What does the same button look like in react-i18next and gt-react? -### 1. General Translation: write copy in JSX, with optional automatic wrapping +With react-i18next, the copy lives in a resource file: -General Translation's `gt-react` lets source copy stay in the component. Mark coherent JSX with [``](/docs/react/reference/components/t), and use [`useGT`](/docs/react/reference/hooks/use-gt) when an API needs a string, such as an input label. The [`gt translate`](/docs/cli/reference/commands/translate) command collects marked content and generates translations through General Translation's service. +```json title="locales/en/translation.json" +{ + "settings": { + "save": "Save changes" + } +} +``` -For a browser-only app, follow the [React SPA setup](/docs/react/react-spa-quickstart). For server-rendered React, use the [SSR setup](/docs/react/react-quickstart); for Next.js, use the [gt-next integration](/docs/react/nextjs-quickstart). Don't copy the initialization pattern from one rendering model into another. +The component looks it up by key: -Consider a settings button. In a conventional react-i18next setup, the component calls `t('settings.save')` and the resource contains the words “Save changes.” With GT, the words stay inside the button, enclosed by [``](/docs/react/reference/components/t). A copy edit is visible alongside the element it belongs to. For rich text, keep the sentence and its inline elements in the same block so translation receives their structure together; add a [`context` note](/docs/react/reference/components/t#context) when the wording alone is ambiguous. +```tsx +import { useTranslation } from 'react-i18next'; -For an existing React SPA with lots of unmarked JSX, [automatic wrapping](/docs/cli/guides/using-auto-jsx) reduces the initial marking work. Enable `files.gt.parsingFlags.enableAutoJsxInjection` in `gt.config.json` and add the GT compiler adapter to your bundler. The compiler inserts translation wrappers at build time and leaves existing GT components untouched. The feature is opt-in; it still needs the SPA runtime setup and a translation generation step. Inspect the extracted text and test dynamic values and rich-text grouping before expanding it across the app. +export function SaveButton() { + const { t } = useTranslation(); + return ; +} +``` -The library is an [independent MIT implementation](https://github.com/generaltranslation/gt), with GT's own ICU and formatting packages. It can render [bundled translations](/docs/react/guides/storing-translations) without an account or runtime GT requests. If you use the hosted service to produce the text, the [Translation Editor](/docs/platform/dashboard/guides/reviewing-translations) gives reviewers a place to correct it; see [pricing](https://generaltranslation.com/pricing) for service terms. +Every other language needs its own resource file, written by hand or sent out for translation. -Choose gt-react when reviewing actual copy in component diffs matters to your team, or when automatic wrapping would help you introduce localization to a React SPA. Use explicit blocks where you want control over which elements form one translation unit. +With gt-react, the copy stays in the component: -### 2. react-i18next: build on the i18next ecosystem +```tsx +import { T } from 'gt-react'; -[react-i18next](https://react.i18next.com/) connects React to i18next. Its hooks render messages from resources, and its Trans component handles text containing React elements. That makes it a candidate when you already have i18next catalogs and want to retain them. +export function SaveButton() { + return ( + + + + ); +} +``` -i18next also supports [source-text keys and default values](https://www.i18next.com/principles/fallback) for readable source copy in code. Its documentation cautions that using source text as keys makes copy changes harder to coordinate between code and translation resources. +Running [`gt translate`](/docs/cli/reference/commands/translate) before your build sends each [``](/docs/react/reference/components/t) block, with its element structure, to General Translation and writes a translation for every target locale. A copy edit shows up in the component diff, and the next run translates it again. -The [i18next plugin ecosystem](https://www.i18next.com/overview/plugins-and-utils) includes translation-loading backends, language detectors, and extraction tools. Its official CLI supports extraction, locale synchronization, and type generation. These are concrete reasons to evaluate it when you need to fit localization into an existing pipeline. +## 1. gt-react: copy in JSX, translations generated -Catalogs do not mean translators must copy files by hand. The project documents a [Locize workflow](https://react.i18next.com/guides/multiple-translation-files) alongside local resources. Choose the integrations you need, then account for their configuration, review process, and production behavior. +gt-react keeps source copy in the component. Wrap JSX in [``](/docs/react/reference/components/t), and use [`useGT`](/docs/react/reference/hooks/use-gt) where an API needs a string, such as an input's `placeholder`. For rich text, keep the sentence and its inline elements in one [``](/docs/react/reference/components/t) block so they're translated together, and add a [`context` prop](/docs/react/reference/components/t#context) when the wording alone is ambiguous. -Choose react-i18next when keeping the i18next message model and integrations matters more than changing how source copy is authored. Check its [SSR guidance](https://react.i18next.com/latest/ssr) if your app renders on the server. +For an app with a lot of unmarked JSX, [automatic JSX injection](/docs/cli/guides/using-auto-jsx) adds the translation wrappers for you at build time. Set `enableAutoJsxInjection` under `files.gt.parsingFlags` in `gt.config.json` and add `@generaltranslation/compiler` to your bundler. It works in React SPAs, server-rendered React apps, and Next.js webpack builds, and leaves existing [``](/docs/react/reference/components/t) blocks alone. Check the extracted text, dynamic values, and rich-text grouping on a few screens before enabling it across the app. -### 3. Lingui: extract and compile translation catalogs +gt-react is [MIT-licensed](https://github.com/generaltranslation/gt) and built on General Translation's own ICU and formatting packages, not on another i18n library. It renders [bundled translations](/docs/react/guides/storing-translations) without a General Translation account or runtime requests. When General Translation generates the translations, reviewers can correct them in the [Translation Editor](/docs/platform/dashboard/guides/reviewing-translations). -[Lingui](https://lingui.dev/introduction) lets you author messages in code, extract them into catalogs, translate them, and compile the result. It supports generated IDs and explicit IDs; PO is the default catalog format, with other formats available. +Setup differs by rendering model: use the [React SPA quickstart](/docs/react/react-spa-quickstart) for browser-only apps, the [React quickstart](/docs/react/react-quickstart) for server-rendered apps, and [gt-next](/docs/react/nextjs-quickstart) for Next.js. -This fits teams that want source copy near the UI while keeping catalogs as the handoff to translators or a localization service. Its [React tutorial](https://lingui.dev/tutorials/react) shows how the authoring and compilation pieces fit together. Server Component applications should also check the [dedicated integration](https://lingui.dev/tutorials/react-rsc). +**Choose gt-react** when you want copy reviewable in component diffs, translations generated as part of your build, or automatic wrapping to localize an existing app quickly. -The tradeoff is ownership of the whole cycle: extraction, translation, compilation, and loading. A successful extraction tells you which messages were found; it does not establish that those messages have been translated or reviewed. +## 2. react-i18next: the i18next ecosystem -Choose Lingui when that catalog workflow suits your team and you want its extraction and compiler tooling. Trial a source-copy change, not just the initial setup, before deciding how to manage IDs and review updates. +[react-i18next](https://react.i18next.com/) connects React to i18next, the most widely used JavaScript i18n framework. Its hooks render messages from JSON resources, and its `Trans` component handles text that contains React elements. -### 4. React Intl: use FormatJS message and formatting APIs +The [i18next plugin ecosystem](https://www.i18next.com/overview/plugins-and-utils) includes translation-loading backends, language detectors, and extraction tools, and the official CLI handles extraction, locale synchronization, and TypeScript type generation. i18next also supports [source text as keys](https://www.i18next.com/principles/fallback), though its documentation warns this makes copy changes harder to coordinate with translations. -[React Intl](https://formatjs.github.io/docs/react-intl/) provides React APIs for messages, plurals, dates, and numbers. Its [message descriptors](https://formatjs.github.io/docs/react-intl/api/) identify messages by ID and can include optional default messages and descriptions. [FormatJS extraction](https://formatjs.github.io/docs/getting-started/message-extraction/) can collect those messages and generate IDs, so adopting it does not necessarily mean inventing every key manually. +react-i18next doesn't translate your resources. Translations come from your team or a service; the i18next team documents a [Locize workflow](https://react.i18next.com/guides/multiple-translation-files). The `gt` CLI can also [translate react-i18next JSON files](/docs/cli/guides/generating-translations) without a migration. -Choose React Intl when your team already works with FormatJS or wants its [ICU MessageFormat syntax](https://formatjs.github.io/docs/core-concepts/icu-syntax/). Reviewers need to understand placeholders and plural branches in that syntax, and your pipeline needs to supply translated messages. +**Choose react-i18next** when you already have i18next resources, or need its plugins for loading and language detection. -Before adopting it in an unfamiliar framework, verify the provider placement, server rendering, and client boundary requirements. A React package supporting message formatting is not evidence that every framework integration works the same way. +## 3. Lingui: extract and compile catalogs -## Make the decision with one feature +[Lingui](https://lingui.dev/introduction) lets you write messages inline with macros, extract them into catalogs, translate them, and compile the result for the app. It supports generated and explicit message IDs, with PO as the default catalog format. Its [React tutorial](https://lingui.dev/tutorials/react) covers the full cycle, and Server Component apps have a [dedicated integration](https://lingui.dev/tutorials/react-rsc). -Choose a feature from your application containing a heading, a named variable, a plural count, an accessible input label, and a formatted price. Translate it into two target languages, then change the source sentence and add another message. +Lingui keeps copy near the UI, but your team owns every step after extraction: translation, review, compilation, and loading. Extraction finds new messages; it doesn't translate them. -Compare the result across four questions: +**Choose Lingui** when your translators or translation service work with PO catalogs and you want Lingui's extraction and compiler tooling. + +## 4. React Intl: FormatJS and ICU MessageFormat + +[React Intl](https://formatjs.github.io/docs/react-intl/) is FormatJS's React library for messages, plurals, dates, and numbers. [Message descriptors](https://formatjs.github.io/docs/react-intl/api/) identify each message by ID, with an optional default message and a description for translators. [FormatJS extraction](https://formatjs.github.io/docs/getting-started/message-extraction/) collects them and can generate the IDs. + +Messages use [ICU MessageFormat](https://formatjs.github.io/docs/core-concepts/icu-syntax/), so reviewers need to read its placeholder and plural syntax, and your pipeline supplies the translated catalogs. Server rendering and client boundaries vary by framework, so check your framework's integration before adopting it. + +**Choose React Intl** when your team already uses FormatJS or wants ICU MessageFormat throughout. + +## How should you test a React i18n library before choosing? + +Pick one feature with a heading, a named variable, a plural count, an accessible input label, and a formatted price. Localize it into two languages with each candidate, then change a source sentence and add a new message. Compare: 1. **Authoring:** Can a reviewer understand the copy and its context in the diff? -2. **Translation:** How does new or changed text reach the person or service translating it? -3. **Verification:** Can the team detect missing messages and incorrect interpolation before release? +2. **Translation:** How does new or changed text reach whoever translates it? +3. **Verification:** Can you catch missing messages and broken variables before release? 4. **Delivery:** Which files or services must be available when the production app renders? -If the trial favors your current library, keep it. [GT's catalog translation workflow](/docs/cli/guides/generating-translations) is also available for react-i18next, so a decision about authoring need not force a change in translation service. +If your current library wins, keep it. The `gt` CLI translates react-i18next catalogs too, so choosing how to author copy doesn't lock in how it gets translated. Before you ship, run the [multilingual app launch checklist](/kb/multilingual-app-launch-checklist). -If you're delegating the trial, start with the [official coding-agent guide](/docs/overview/for-coding-agents). Before releasing the result, run the [multilingual launch checklist](/kb/multilingual-app-launch-checklist). +General Translation is used by developer teams at Cursor, Ramp, Profound, Cognition, Sierra, and ClickHouse. To try it, start with the [React quickstart](/docs/react/react-quickstart). ## Common questions -### Is avoiding JSON the main selection criterion? +### Which React i18n library translates my app automatically? + +gt-react. react-i18next, Lingui, and React Intl render translations you supply. With gt-react, [`gt translate`](/docs/cli/reference/commands/translate) generates translations for every target locale using your code as context. + +### Is react-i18next or React Intl better? + +Neither is better in general. react-i18next suits teams that want JSON resources and i18next's plugins. React Intl suits teams standardized on FormatJS and ICU MessageFormat. Both leave translation to your team or a separate service. + +### Which React i18n library supports Server Components? + +For Next.js App Router apps, use [gt-next](/docs/react/nextjs-quickstart), which supports Server and Client Components. Lingui has a [dedicated RSC integration](https://lingui.dev/tutorials/react-rsc), and next-intl is another App Router option. + +### Can I use General Translation without leaving react-i18next? + +Yes. The `gt` CLI detects react-i18next and translates its JSON resources while preserving their syntax. See [Generating translations](/docs/cli/guides/generating-translations). + +### Do I still need JSON translation files with gt-react? -Usually the more useful question is which maintenance work you want to remove. Inline authoring can still produce JSON output, and a catalog workflow can automate synchronization. The [guide to i18n without translation files](/kb/i18n-without-translation-files) explains the distinction between source authoring and generated output. +Not as source files. You write copy inline, and translations are generated as files in your build or served from General Translation's CDN. See [i18n without translation files](/kb/i18n-without-translation-files). -### Does an i18n library translate the app for me? +## Key takeaways -A library renders localized content; the translation workflow produces that content. General Translation connects those steps through its SDKs and CLI. Other setups can pair their library with a translation platform. Compare the complete workflow, including review and delivery, rather than assuming a catalog-based approach is manual or an inline approach needs no maintenance. +- gt-react, react-i18next, Lingui, and React Intl all render and format translations in React. Only gt-react also generates them. +- gt-react keeps copy inline in JSX and can wrap existing JSX automatically at build time. +- react-i18next, Lingui, and React Intl rely on catalogs that your team or a translation service fills in. +- You can keep react-i18next and still use General Translation to translate its resources. diff --git a/kb/multilingual-app-launch-checklist.mdx b/kb/multilingual-app-launch-checklist.mdx index c5145062d..e4f4010de 100644 --- a/kb/multilingual-app-launch-checklist.mdx +++ b/kb/multilingual-app-launch-checklist.mdx @@ -1,6 +1,6 @@ --- title: What should I check before launching a multilingual app? -summary: Test translation coverage, language selection, variables and plurals, regional formatting, layout, accessibility, and production delivery in every supported locale, using complete user workflows and explicit expected results. Public multilingual pages also need crawlable language URLs and consistent search metadata. +summary: "Before launching a multilingual app, test nine things in every supported locale: complete user journeys including errors, language detection and switching, variables and plurals, currency and time zones, text expansion, right-to-left layout, accessibility, production translation delivery, and crawlable language URLs for SEO. Each check needs an explicit pass condition." date: 2026-10-16 category: internationalization authors: [jackie] @@ -9,7 +9,19 @@ related: [best-react-i18n-library, i18n-without-translation-files, how-to-handle A translated homepage can look finished while the checkout, validation errors, or password-reset flow still uses the source language. Start with the paths a user needs to complete, and test those paths in the production build. -These nine checks apply to web applications. Use every supported locale for content checks, and include representative devices and browsers for layout and interaction. The SEO check applies to public pages you want indexed. +Before launching a multilingual web app, check these nine things in every supported locale: + +1. **Whole journeys are translated**, including loading, empty, and error states, emails, and notifications. +2. **Language selection is consistent** on first visits, after switching, and on return visits. +3. **Variables and plurals are correct** for every plural category your languages use. +4. **Currency and time zone are set explicitly**, separately from the UI language. +5. **Layouts survive text expansion** on narrow screens and with browser zoom. +6. **Right-to-left languages** have the correct direction, layout, and mixed-direction text. +7. **Assistive technology gets the right language**, labels, and accessible names. +8. **The production build ships complete translations**, and new copy gets translated before release. +9. **Public pages have crawlable language URLs** with translated metadata and `hreflang`. + +Test content in every supported locale, and test layout and interaction on representative devices and browsers. Check 9 applies only to public pages you want indexed. ## Check content and language behavior @@ -19,11 +31,7 @@ Choose a critical journey such as creating an account or completing a purchase. **Pass condition:** Each surface uses reviewed target-language content, apart from intentional exceptions such as a product name. No raw keys, missing-message markers, or unexplained source-language fallbacks appear. -General Translation's [Context Groups](/docs/platform/dashboard/guides/defining-context-for-translations) apply shared Glossary terms and Custom Prompts across projects, so your app, documentation, and notifications can use the same product terminology. Projects and reviewer seats are [unlimited](https://generaltranslation.com/pricing). Assign the intended groups before generating translations; changes to context guide new translations rather than silently rewriting existing ones. - -Reviewers work in the [Dashboard Translation Editor](/docs/platform/dashboard/guides/reviewing-translations), where they can correct wording directly. Enterprise adds approval controls for governance. For teams that edit generated local files, [`gt save-local`](/docs/cli/reference/commands/save-local) uploads those edits for reuse in later translation runs; this synchronization is opt-in. - -If your pipeline uses [`gt translate`](/docs/cli/reference/commands/translate), confirm that its output is the version included in the release. The manual alternative, [`gt generate`](/docs/cli/reference/commands/generate), produces source templates that still need translated text. +**With General Translation:** Confirm that the output of [`gt translate`](/docs/cli/reference/commands/translate) is the version included in the release. ([`gt generate`](/docs/cli/reference/commands/generate) only writes source templates, which still need translated text.) Reviewers correct wording in the [Dashboard Translation Editor](/docs/platform/dashboard/guides/reviewing-translations); if your team edits the generated files in the repository instead, run [`gt save-local`](/docs/cli/reference/commands/save-local) so later runs keep those edits. To keep product terms consistent across your app, docs, and notifications, assign shared Glossary terms and Custom Prompts with [Context Groups](/docs/platform/dashboard/guides/defining-context-for-translations) before generating translations. Context changes apply to new translations; they don't rewrite existing ones. ### 2. Verify first visits, switching, and return visits @@ -31,7 +39,9 @@ Test a fresh browser, an explicit language choice, a reload, a deep link, and an **Pass condition:** The app follows that policy consistently, and a user can recover from an unwanted language choice. For server-rendered apps, inspect the initial response as well as the hydrated page. -Use [locale configuration](/docs/react/guides/managing-locales) to define supported languages. Locale identifiers follow BCP 47: `es-MX` and `es-AR` can be separate targets for Mexican and Argentine Spanish. Test each regional target you ship. A cookie-based switcher and locale-prefixed routes serve different needs; check the app's actual URL behavior. +Locale identifiers follow BCP 47: `es-MX` and `es-AR` can be separate targets for Mexican and Argentine Spanish. Test each regional target you ship. A cookie-based switcher and locale-prefixed routes serve different needs; check the app's actual URL behavior. + +**With General Translation:** Define supported languages, including regional targets, in your [locale configuration](/docs/react/guides/managing-locales). ### 3. Exercise variables and plural categories @@ -39,7 +49,7 @@ Test counts including 0, 1, 2, and larger values, then add cases for your target **Pass condition:** Values remain intact, the sentence reads correctly, and every required plural form has usable content. Unicode's [plural rules](https://cldr.unicode.org/index/cldr-spec/plural-rules) describe why one English singular/plural test pair is insufficient. -General Translation's [``](/docs/react/reference/components/plural) follows the locale's plural rules: English has two cardinal categories, while Arabic has six. Use [``](/docs/react/reference/components/branch) when wording depends on an explicit value such as a person's grammatical gender, and [``](/docs/react/reference/components/var) for dynamic text such as a name. Values inside that variable wrapper are not sent to the translation API. The [React pluralization article](/kb/how-to-handle-plurals-in-react) covers the implementation pattern. +**With General Translation:** [``](/docs/react/reference/components/plural) follows the locale's plural rules: English has two cardinal categories, while Arabic has six. Use [``](/docs/react/reference/components/branch) when wording depends on an explicit value such as a person's grammatical gender, and [``](/docs/react/reference/components/var) for dynamic text such as a name. Values inside that variable wrapper are not sent to the translation API. The [React pluralization article](/kb/how-to-handle-plurals-in-react) covers the implementation pattern. ## Check formatting, layout, and accessibility @@ -68,7 +78,7 @@ new Intl.DateTimeFormat('en-GB', { **Pass condition:** Separators, currency identity, calendar date, and displayed time match the product's intended meaning. Include a daylight-saving transition when your supported time zones observe one. The [number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/NumberFormat) and [date](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat) APIs expose these choices separately. -In General Translation, [``](/docs/react/reference/components/currency), [``](/docs/react/reference/components/datetime), and [``](/docs/react/reference/components/num) format values using the active locale. Set the currency and time zone for the business meaning you intend; changing the UI language should not change the amount owed or the instant an event occurs. +**With General Translation:** [``](/docs/react/reference/components/currency), [``](/docs/react/reference/components/datetime), and [``](/docs/react/reference/components/num) format values using the active locale. Set the currency and time zone for the business meaning you intend; changing the UI language should not change the amount owed or the instant an event occurs. ### 5. Test text expansion across screen sizes @@ -98,7 +108,7 @@ Build from a clean checkout using the release process, then run that build with **Pass condition:** The app serves the intended translations without relying on files left over from development. Missing assets or failed generation cause a visible failure or an explicitly accepted fallback, rather than a silent partial release. -With General Translation, run [`gt validate`](/docs/cli/reference/commands/validate) to catch supported inline-translation errors before an API call, then put the [incremental translation step before the build](/docs/cli/guides/generating-translations). It reuses earlier translations and translates changed content, so new copy can ship translated in the release that adds it. [Branch tracking](/docs/cli/guides/branching) keeps parallel development branches separate. [Locadex automations](/docs/platform/locadex/guides/configuring-automations) can handle translation updates through pull requests. Test the configured trigger with a source-copy change as part of this release check. +**With General Translation:** Run [`gt validate`](/docs/cli/reference/commands/validate) to catch supported inline-translation errors before an API call, then put the [incremental translation step before the build](/docs/cli/guides/generating-translations). It reuses earlier translations and translates changed content, so new copy can ship translated in the release that adds it. [Branch tracking](/docs/cli/guides/branching) keeps parallel development branches separate. [Locadex automations](/docs/platform/locadex/guides/configuring-automations) can handle translation updates through pull requests. Test the configured trigger with a source-copy change as part of this release check. With the [local storage workflow](/docs/react/guides/storing-translations), the app serves bundled translations without runtime calls to General Translation; updates ship in a new build. With CDN delivery, published edits can reach the app without a redeploy, subject to its translation version and cache settings. Test that update path. Keep private translation tooling credentials in the build environment, outside browser bundles. @@ -114,4 +124,22 @@ Path prefixes, language subdomains, and country domains can provide separate lan Record the build, locale, journey, browser or device, expected result, actual result, and reviewer. Assign an owner to failures. Treat a missing checkout translation or unreadable primary action differently from a minor wording preference, and make any accepted fallback explicit. -General Translation's free [Report Card](https://generaltranslation.com/report-card) can provide a starting assessment of a public site's localization. Pair it with the journey checks above, especially authenticated flows and failure states. The [coding-agent setup guide](/docs/overview/for-coding-agents) can help automate repeatable checks and collect evidence; use the Translation Editor for the language review that completes the release. +For a quick first pass on a public site, General Translation's free [Report Card](https://generaltranslation.com/report-card) scores its localization. It can't see authenticated flows or failure states, so pair it with the journey checks above. + +## Common questions + +### How do you test a multilingual app? + +Run complete user journeys in every supported locale on a production build, including error states, emails, and notifications. Check plurals, variables, currency, time zones, layout, right-to-left text, and accessibility, and record a pass condition for each check. + +### What is the most commonly missed localization bug? + +Untranslated failure states. Error messages, form validation, empty states, and transactional emails are often still in the source language after the main screens are translated. Test them deliberately in check 1. + +### What is pseudolocalization? + +Pseudolocalization replaces source text with longer, accented placeholder text so you can find layout overflow and unmarked strings before real translations exist. It doesn't replace testing real languages. See [Lingui's pseudolocalization guide](https://lingui.dev/guides/pseudolocalization). + +### Do multilingual pages need separate URLs for SEO? + +Yes, for pages you want indexed. Google recommends a [separate URL for each language version](https://developers.google.com/search/docs/specialty/international/managing-multi-regional-sites), linked with `hreflang`. A cookie or `Accept-Language` header alone doesn't create crawlable versions. For Next.js, see [multilingual Next.js SEO](/kb/multilingual-nextjs-seo).