# generaltranslation: General Translation Core SDK: FAQs
URL: https://generaltranslation.com/en-US/docs/core/faqs.mdx
---
title: FAQs
description: Frequently asked questions about generaltranslation (core library)
---
### What is the core library for?
The `generaltranslation` package provides locale utilities (parsing, comparing, formatting) and direct access to the GT translation API. It's the foundation that powers gt-next, gt-react, and gt-react-native under the hood.
### Can I use the core library on its own?
Yes. If you need locale utilities like [`getLocaleName`](/docs/core/functions/locales/get-locale-name), [`isValidLocale`](/docs/core/functions/locales/is-valid-locale), or [`formatDateTime`](/docs/core/functions/formatting/format-date-time) without a React framework, you can use the core library directly.
### Do I need an API key for locale utilities?
No. Locale utility functions work entirely offline. You only need an API key if you're calling the [translation methods](/docs/core/class/methods/translation/translate) on the GT class.
### What's the difference between the standalone functions and the class methods?
The standalone functions (e.g., `getLocaleName()`) are stateless utilities you can import and call directly. The `GT` class wraps the same functionality plus translation API access, configured with your API key and project ID.
# generaltranslation: General Translation Core SDK: Overview
URL: https://generaltranslation.com/en-US/docs/core.mdx
---
title: Overview
description: Overview of the generaltranslation library
---
## Introduction
The `generaltranslation` library serves as GT's core i18n library housing utility functions and classes for translation and formatting.
It is often used with framework packages like `gt-next` and `gt-react`, but can be used as a standalone library.
import Video from '@/components/Video';
```typescript title="index.ts"
import { GT } from 'generaltranslation';
const gt = new GT({
apiKey: 'your-api-key',
projectId: 'your-project-id',
sourceLocale: 'en',
targetLocale: 'es',
});
// Translate content
const result = await gt.translate('Hello, world!', 'es');
// "¡Hola, mundo!"
// Format numbers, dates, currencies
const formattedPrice = gt.formatNum(29.99, { style: 'currency', currency: 'USD' });
const formattedDate = gt.formatDateTime(new Date());
// "$29.99"
// "9/25/2025"
// Work with locales
const localeProps = gt.getLocaleProperties('fr-CA');
const isValid = gt.isValidLocale('de');
// { language: "fr", region: "CA", ... }
// true
```
---
## Installation
```bash
npm install generaltranslation
```
```bash
yarn add generaltranslation
```
```bash
bun add generaltranslation
```
```bash
pnpm add generaltranslation
```
---
## Examples
There are two major types of translation: string translation and file translation.
### Setup
To enable translation, you need to provide a project ID and API key.
Check out the [`constructor`](/docs/core/class/constructor) method for more information.
```typescript
const gt = new GT({
apiKey: 'your-api-key',
projectId: 'your-project-id',
targetLocale: 'es',
});
```
### String translation
Check out the [`translate`](/docs/core/class/methods/translation/translate) method for more information.
```typescript
try {
const result = await gt.translate('Hello, world!');
console.log(result); // "¡Hola, mundo!"
} catch (error) {
console.error('Translation failed:', error.message);
}
```
### File translation
Files are translated as jobs.
You launch a job by uploading a file.
Uploading many files will launch many jobs.
Check out the [`uploadSourceFiles`](/docs/core/class/methods/translation/upload-source-files)
and [`queryFileData`](/docs/core/class/methods/translation/query-file-data) methods for more information.
```typescript
// Files to upload
const files = [
{
source: {
fileName: 'src/components/Button.tsx',
fileFormat: 'TSX',
locale: 'en',
content: '...',
},
},
];
// Upload source files
await gt.uploadSourceFiles(files);
```
---
## Table of contents
### GT class
Main class for translation and locale functionality:
- **[Constructor](/docs/core/class/constructor)** - Initialize GT instance with configuration
- **[setConfig](/docs/core/class/set-config)** - Update GT instance configuration
#### Translation methods
- **[translate](/docs/core/class/methods/translation/translate)** - Core translation functionality
- **[translateMany](/docs/core/class/methods/translation/translate-many)** - Batch translation
- **[setupProject](/docs/core/class/methods/translation/setup-project)** - Project initialization
- **[checkJobStatus](/docs/core/class/methods/translation/check-job-status)** - Check job progress
- **[getProjectData](/docs/core/class/methods/translation/get-project-data)** - Retrieve project information
- **[uploadSourceFiles](/docs/core/class/methods/translation/upload-source-files)** - Upload files for translation
- **[uploadTranslations](/docs/core/class/methods/translation/upload-translations)** - Upload pre-existing translations
- **[enqueueFiles](/docs/core/class/methods/translation/enqueue-files)** - Queue files for processing
- **[queryFileData](/docs/core/class/methods/translation/query-file-data)** - Check translation status
- **[downloadFile](/docs/core/class/methods/translation/download-file)** - Download single file
- **[downloadFileBatch](/docs/core/class/methods/translation/download-file-batch)** - Download multiple files
- **[querySourceFile](/docs/core/class/methods/translation/query-source-file)** - Query source file information
#### Formatting methods
- **[formatMessage](/docs/core/class/methods/formatting/format-message)** - Internationalized text formatting
- **[formatNum](/docs/core/class/methods/formatting/format-num)** - Number formatting
- **[formatDateTime](/docs/core/class/methods/formatting/format-date-time)** - Date and time formatting
- **[formatRelativeTime](/docs/core/class/methods/formatting/format-relative-time)** - Relative time formatting with explicit unit
- **[formatRelativeTimeFromDate](/docs/core/class/methods/formatting/format-relative-time-from-date)** - Relative time formatting from a Date
- **[formatCutoff](/docs/core/class/methods/formatting/format-cutoff)** - Text cutoff formatting
- **[formatListToParts](/docs/core/class/methods/formatting/format-list-to-parts)** - List formatting to parts
#### Locale methods
- **[getLocaleName](/docs/core/class/methods/locales/get-locale-name)** - Get locale display name
- **[getLocaleProperties](/docs/core/class/methods/locales/get-locale-properties)** - Get comprehensive locale information
- **[getLocaleDirection](/docs/core/class/methods/locales/get-locale-direction)** - Get text direction for locale
- **[getLocaleEmoji](/docs/core/class/methods/locales/get-locale-emoji)** - Get flag emoji for locale
- **[getRegionProperties](/docs/core/class/methods/locales/get-region-properties)** - Get region information and properties
- **[isValidLocale](/docs/core/class/methods/locales/is-valid-locale)** - Validate locale code
- **[resolveAliasLocale](/docs/core/class/methods/locales/resolve-alias-locale)** - Convert canonical locales to aliases
- **[resolveCanonicalLocale](/docs/core/class/methods/locales/resolve-canonical-locale)** - Convert alias locales to canonical form
- **[standardizeLocale](/docs/core/class/methods/locales/standardize-locale)** - Standardize locale code formatting
- **[isSameDialect](/docs/core/class/methods/locales/is-same-dialect)** - Check if locales represent same dialect
- **[isSameLanguage](/docs/core/class/methods/locales/is-same-language)** - Check if locales represent same language
- **[isSupersetLocale](/docs/core/class/methods/locales/is-superset-locale)** - Check locale hierarchy relationships
- **[determineLocale](/docs/core/class/methods/locales/determine-locale)** - Find best matching locale from preferences
- **[requiresTranslation](/docs/core/class/methods/locales/requires-translation)** - Determine if translation is needed
### Utility functions
#### Formatting functions
- **[formatMessage](/docs/core/functions/formatting/format-message)** - Standalone text formatting
- **[formatNum](/docs/core/functions/formatting/format-num)** - Standalone number formatting
- **[formatDateTime](/docs/core/functions/formatting/format-date-time)** - Standalone date/time formatting
- **[formatRelativeTime](/docs/core/functions/formatting/format-relative-time)** - Standalone relative time formatting
- **[formatRelativeTimeFromDate](/docs/core/functions/formatting/format-relative-time-from-date)** - Standalone relative time from Date formatting
- **[formatCutoff](/docs/core/functions/formatting/format-cutoff)** - Standalone text cutoff formatting
- **[formatListToParts](/docs/core/functions/formatting/format-list-to-parts)** - Standalone list formatting to parts
#### Locale functions
- **[getLocaleName](/docs/core/functions/locales/get-locale-name)** - Standalone locale name utility
- **[getLocaleProperties](/docs/core/functions/locales/get-locale-properties)** - Standalone locale properties
- **[getLocaleDirection](/docs/core/functions/locales/get-locale-direction)** - Standalone text direction utility
- **[getLocaleEmoji](/docs/core/functions/locales/get-locale-emoji)** - Standalone emoji utility
- **[getRegionProperties](/docs/core/functions/locales/get-region-properties)** - Standalone region properties utility
- **[isValidLocale](/docs/core/functions/locales/is-valid-locale)** - Standalone locale validation
- **[resolveAliasLocale](/docs/core/functions/locales/resolve-alias-locale)** - Standalone alias locale resolution
- **[standardizeLocale](/docs/core/functions/locales/standardize-locale)** - Standalone locale standardization
- **[isSameDialect](/docs/core/functions/locales/is-same-dialect)** - Standalone dialect comparison
- **[isSameLanguage](/docs/core/functions/locales/is-same-language)** - Standalone language comparison
- **[isSupersetLocale](/docs/core/functions/locales/is-superset-locale)** - Standalone locale hierarchy checking
- **[determineLocale](/docs/core/functions/locales/determine-locale)** - Standalone locale negotiation
- **[requiresTranslation](/docs/core/functions/locales/requires-translation)** - Standalone translation requirement checking
### Types and interfaces
TypeScript definitions:
- **[GTConstructorParams](/docs/core/types/gt-constructor-params)** - Configuration options
- **[LocaleProperties](/docs/core/types/locale-properties)** - Comprehensive locale information
- **[TranslationResult](/docs/core/types/translation-result)** - Translation response types
- **[TranslateManyResult](/docs/core/types/translate-many-result)** - Batch translation response
- **[FileToTranslate](/docs/core/types/file-to-translate)** - File translation configuration
- **[EnqueueFilesOptions](/docs/core/types/enqueue-files-options)** - File queuing options
- **[Entry](/docs/core/types/Entry)** - Translation entry structure
- **[EntryMetadata](/docs/core/types/entry-metadata)** - Entry metadata information
- **[Content](/docs/core/types/Content)** - Content type definitions
- **[Variable](/docs/core/types/Variable)** - Variable structure
- **[VariableType](/docs/core/types/variable-type)** - Variable type definitions
- **[JsxElement](/docs/core/types/jsx-element)** - JSX element type
- **[JsxChild](/docs/core/types/jsx-child)** - JSX child type
- **[JsxChildren](/docs/core/types/jsx-children)** - JSX children type
- **[DataFormat](/docs/core/types/data-format)** - Data format specifications
- **[CustomMapping](/docs/core/types/custom-mapping)** - Custom mapping configuration
---
## Next steps
- **[Get started with the GT class](/docs/core/class/constructor)**
- **[Explore translation methods](/docs/core/class/methods/translation/translate)**
- **[Learn about locale utilities](/docs/core/class/methods/locales/get-locale-name)**
- **[Check out formatting options](/docs/core/class/methods/formatting/format-message)**
- **[Browse standalone functions](/docs/core/functions/formatting/format-message)**
For framework-specific usage, see the [Next.js](/docs/next) or [React](/docs/react) documentation.
# generaltranslation: General Translation Core SDK: Locales
URL: https://generaltranslation.com/en-US/docs/core/locales.mdx
---
title: Locales
description: What are locales and how are they used in the General Translation stack?
---
A locale is **a language or dialect**.
For example, `en-US` is a locale code, which refers to the English language as spoken in the United States of America.
Locales can be general or specific. For example:
- `en` is English
- `en-US` is English as spoken in the United States of America
- `zh` is Chinese
- `zh-Hant` is Chinese, written with traditional characters
- `zh-Hant-HK` is Chinese, written with traditional characters, as spoken in Hong Kong
### Constructing locale codes
General Translation uses the [BCP 47 Language Tag](https://www.techonthenet.com/js/language_tags.php) standard to define locale codes.
BCP 47 Language Tags are the Internet Best Current Practices (BCP) standard for identifying languages in both spoken and written forms.
These tags provide a uniform way to specify languages, letting GT adapt content, format, and behavior based on the user's locale.
Locale codes consist of one or more subtags separated by the `-` character. These subtags are:
- **Language code** (required): Represents the primary language, e.g., `en` for English, `es` for Spanish.
Language codes follow [ISO-639](https://wikipedia.org/wiki/List_of_ISO_639_language_codes).
- **Script code** (optional): Indicates the writing system, e.g., `Latn` for the Latin alphabet.
Script codes follow [ISO-15924](https://en.wikipedia.org/wiki/ISO_15924).
- **Region code** (optional): Specifies a country or region, e.g., `US` for the United States, `FR` for France.
Region codes follow [ISO-3166](https://en.wikipedia.org/wiki/ISO_3166-2).
For example, `zh-Hant-HK` is:
- `zh`, the language code for Chinese
- `Hant`, the script code for Traditional Chinese characters
- `HK`, the region code for Hong Kong
Together, `zh-Hant-HK` means "Chinese, written in traditional characters, as spoken in Hong Kong".
### List of supported locales [#supported-locales]
See the [list of supported locales](/docs/platform/supported-locales) for a searchable list of all locales currently supported by General Translation.
Technically, the library supports any validly constructed tag, including private use codes with no widely recognized meaning.
However, the platform will only translate
### Equivalent locale tags
Sometimes, multiple locale tags are functionally equivalent.
For example, you could write:
- `fr`, meaning "French"
- `fr-FR`, meaning "French as spoken in France"
- `fr-FR-Latn`, meaning "French as spoken in France, written in the Latin alphabet"
The General Translation libraries and platform usually don't distinguish between these equivalent codes,
since translating between them is impossible.
### Commonly used locale codes
| Locale code | Language | Script | Region | Description |
|---------------|-------------|---------------------|-----------------|-----------------------------------------------|
| `en` | English | ― | ― | English |
| `en-US` | English | ― | United States | English as spoken in the United States |
| `en-GB` | English | ― | United Kingdom | English as spoken in the United Kingdom |
| `es` | Spanish | ― | ― | Spanish |
| `es-419` | Spanish | ― | Latin America | Spanish as spoken in Latin America |
| `fr` | French | ― | ― | French |
| `fr-CA` | French | ― | Canada | French as spoken in Canada |
| `de` | German | ― | ― | German |
| `de-AT` | German | ― | Austria | German as spoken in Austria |
| `ru` | Russian | ― | ― | Russian |
| `zh-CN` | Chinese | ― | Mainland China | Chinese as spoken in Mainland China |
| `zh-Hant` | Chinese | Traditional Chinese | ― | Chinese, Traditional script |
| `zh-Hant-SG` | Chinese | Traditional Chinese | Singapore | Traditional Chinese as spoken in Singapore |
| `ja` | Japanese | ― | ― | Japanese |
| `ko` | Korean | ― | ― | Korean |
| `pt-BR` | Portuguese | ― | Brazil | Portuguese as spoken in Brazil |
| `it` | Italian | ― | ― | Italian |
### Next steps
- See our [List of Supported Locales](/docs/platform/supported-locales) to find the language tags available in General Translation.
- Refer to the official [IETF Language Tag Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)
and the [BCP 47 Language Tag standard](https://www.techonthenet.com/js/language_tags.php) for more information.
# generaltranslation: General Translation Core SDK: Quickstart
URL: https://generaltranslation.com/en-US/docs/core/quickstart.mdx
---
title: Quickstart
description: Quickstart guide for the generaltranslation library
---
## Overview
This guide will walk you through the basics of using the generaltranslation library.
We will cover string translation and file translation.
---
## Translate your first string
### 1. Get your environment variables
The very first step is to create a `GT_PROJECT_ID` and `GT_API_KEY`.
This is completely free, and will give you access to the translation services.
Navigate to the [`API Keys` page](https://dash.generaltranslation.com/api-keys) click `Create API Key`.
Choose a name for your API key, and click `Create`.

General Translation offers very high free rate limits to support personal projects, solo developers, and the community.
### 2. Initialize the GT class
Initialize the [`GT`](/docs/core/class/constructor) class and securely pass your `GT_PROJECT_ID` and `GT_API_KEY`.
```typescript title="src/index.ts"
import { GT } from 'generaltranslation';
const gt = new GT({
projectId: 'your-project-id',
apiKey: 'your-api-key',
});
```
### 3. Translate your first string
Call the [`translate`](/docs/core/class/methods/translation/translate) method to translate your string.
Pass the string you want to translate, and the target locale.
```typescript title="src/index.ts"
const result = await gt.translate('Hello, world!', 'es'); // Spanish
if (result.success) {
console.log(result.translation); // "¡Hola, mundo!"
} else {
console.error(`Translation failed: ${result.error}`);
}
```
If you want to look up a locale code, check out the [supported locales](/docs/platform/supported-locales) page.
---
## Translate your first file
This guide assumes you already have followed steps 1 and 2 of the [Translate
your first string](/docs/core/quickstart#translate-your-first-string) guide
and have a `GT_PROJECT_ID`, `GT_API_KEY`, and a `GT` class instance.
Let's say you wanted to translate a file called `en.json` to Spanish.
```json title="en.json"
{
"hello": "Hello",
"world": "World"
}
```
In order to translate a file, you need to follow these four steps:
1. Upload the file
2. Enqueue the file for translation
3. Check on the file status (optional)
4. Download the translated file.
#### Why not just one call? Typically, people will want to translate many
files at once. By breaking these into four clear steps, it gives users much
more flexibility in how they can use the API.
### 1. Upload the file
Uploading files returns a list of file references with the [`uploadSourceFiles`](/docs/core/class/methods/translation/upload-source-files) method.
This allows you to later check the enqueue the file for translation, check the status of the file, and download the translated file.
```typescript title="src/index.ts"
import fs from 'fs';
import path from 'path';
import { FileUpload } from 'generaltranslation';
// (i) Read the content of a file
const filePath = path.join(process.cwd(), 'en.json');
const fileContents = fs.readFileSync(filePath, 'utf8');
// (ii) Format the file contents
const fileUpload: FileUpload = {
content: fileContents,
fileName: filePath,
fileFormat: 'JSON',
locale: 'en',
};
const files = [ { source: fileUpload } ];
// (iii) Upload the file
const { uploadedFiles } = await gt.uploadSourceFiles(
files,
{
sourceLocale: 'en'
}
);
```
This will return a list of file references:
```ts title="Output"
[
{
fileId: '41726368696562616c64204d6342616c64792074686973206973206a6f6b652e',
versionId: '427269616e204c6f75206d6f7265206c696b65204c696f6e2042726f20686121',
branchId: '123456789',
fileName: '/Users/demo/en.json',
fileFormat: 'JSON'
}
]
```
### 2. Enqueue the file for translation
The next step is to select the target locales for the translation with the [`enqueueFiles`](/docs/core/class/methods/translation/enqueue-files) method.
In this case, we will translate to Spanish.
```typescript title="src/index.ts"
const fileUploadRef = {
fileId: uploadedFiles[0].fileId,
versionId: uploadedFiles[0].versionId,
branchId: uploadedFiles[0].branchId,
fileName: uploadedFiles[0].fileName,
fileFormat: uploadedFiles[0].fileFormat,
};
const enqueueResult = await gt.enqueueFiles(
[fileUploadRef],
{
sourceLocale: 'en',
targetLocales: ['es'],
});
```
This will return a result with job information:
```ts title="Output"
{
jobId: 'job-123456',
locales: [ 'es' ],
message: 'Creating 1 translation(s).'
}
```
### 3. Check on the file status
Okay, now that the file is uploaded, when do we know it's ready for download?
We can use the [`queryFileData`](/docs/core/class/methods/translation/query-file-data) method to check on the file status.
```typescript title="src/index.ts"
const { fileId, versionId, branchId } = uploadedFiles[0];
const status = await gt.queryFileData({
translatedFiles: [{
fileId,
versionId,
branchId,
locale: 'es'
}]
});
```
If the file is still being translated, `completedAt` will be `null`. When complete, it will contain a timestamp.
```ts title="Output"
{
translatedFiles: [
{
fileId: '41726368696562616c64204d6342616c64792074686973206973206a6f6b652e',
versionId: '427269616e204c6f75206d6f7265206c696b65204c696f6e2042726f20686121',
branchId: '123456789',
locale: 'es',
completedAt: '2024-01-15T12:00:00Z',
...
}
]
}
```
### 4. Download the translated file
Finally, we can download the translated file with the [`downloadFile`](/docs/core/class/methods/translation/download-file) method.
```typescript title="src/index.ts"
const { fileId, branchId } = uploadedFiles[0];
const content = await gt.downloadFile({
fileId,
branchId,
locale: 'es',
});
```
This will return the translated file content:
```ts title="Output"
{
"hello": "Hola",
"world": "Mundo"
}
```
# General Translation Key Concepts: Dynamic Content
URL: https://generaltranslation.com/en-US/docs/key-concepts/dynamic-content.mdx
---
title: Dynamic Content
description: A brief overview of working with Dynamic Content in GT.
---
## Overview
**Dynamic Content** is generally any content that can change based on the user, context, environment, etc.
This exists in contrast to **Static Content**, which remains the same regardless of the user, context, environment, etc.
TL;DR
* Static Content never changes (raw strings, text, etc.).
* Dynamic Content can change (names, emails, time, language, etc.).
**What is Static Content?**
Static Content generally refers to any raw text that exists in the bundle that is served to your users.
A good rule of thumb is any text or strings that a developer can read in the source code is static text.
For example, consider this file:
```jsx title="Landing.jsx" copy
export default function Landing() {
return (
<> Welcome to my app!>
);
}
```
The text, "Welcome to my app!", is Static Content because it never changes.
But, what if we wanted to change the page such that it would respond if the user was logged in:
```jsx title="Landing.jsx" copy
export default function Landing(user) {
if (user) {
return (
Welcome to my app, {user.name}!
);
}
return (
Welcome to my app!
);
}
```
Even though these two phrases are being conditionally rendered, these two phrases are both considered static text.
Remember our rule of thumb: we can see this content by reading the source code in `landing.jsx`.
However, `{user.name}` is considered dynamic content, because it can change.
We cannot know what will get rendered on the user's screen by just reading the `landing.jsx` file.
## "To Tx or not to Tx"
Sometimes, we want to translate dynamic content, but other times we want it to remain the same.
A good example would be a user's email address or name.
Another example might be a bank account balance or a user's SSN.
Such items are (1) not likely to need translation when your app is being rendered in a different language and (2) can vary (in this case between each user).
### Example
```jsx title="Greeting.jsx" copy
import { T, Var } from 'gt-next'
export default function Greeting(name) {
return (
Hello, {name} !
);
}
```
As far as translation goes this has two benefits:
1. You do not have to create a translation for every possible name.
* Using ``, we only generate one translation that essentially would look like this:
* \`¡Hola, $\{name\}!\`
* If we do not use ``, we would have to perform an on-demand translation for every unique name:
* "¡Hola, Alice!", "¡Hola, Bob!", "¡Hola, Charlie!", "¡Hola, David!", ...
2. You also don't have to worry about the names themselves changing into a translated form of their name: (i.e. "¡Hola, Alicia!", "¡Hola, Roberto!", ...).
**Note:** The ``, ``, ``, and `` components are available in `gt-next`, `gt-react`, and `gt-react-native`.
As you can see, the `` component should be used to wrap any contents that should remain the same regardless of locale.
This way, we avoid the need to create translations for every possible value of the dynamic content.
By wrapping private information in a `` component, you can ensure that the information is not sent to the General Translation API.
**Exceptions**
The exceptions to the statement above are (1) in the case of a nested `` component used inside of a `` component (ie, the children of the nested `` component will be translated)
or (2) when data is passed intentionally to our API via some other means within a child of the `` component (i.e., a fetch call).
However, this is not the intended use of the `` component nor the General Translation API and doing so can harm load times and performance.
# General Translation Key Concepts: Private Information
URL: https://generaltranslation.com/en-US/docs/key-concepts/private-information.mdx
---
title: Private Information
description: A brief overview of working with Private Information in GT.
---
## Overview
Private information is generally any information that should remain private.
For example, a user's Social Security Number (SSN), Tax Identification Number (TIN), or email address.
In order to keep this information private while translating, we use the `` component (available in `gt-next`, `gt-react`, and `gt-react-native`).
The `` component is used to wrap any content that should not be shared,
and the content inside the `` component will always remain the same.
This is great for names, emails, addresses, etc.
Sometimes, we do want to display private information, but we still need to reformat it based on the user's preferred languages, regional regulations, etc.
For example, we might want to display a user's bank account balance in their local currency.
In these cases, we instead use either ``, ``, or `` components.
### Example
The `` component is also useful for displaying private information.
```jsx title="PrivateInfo.jsx" copy
import { T, Var } from 'gt-next'
export default function PrivateInfo(email) {
return (
Your email address is {email} .
);
}
```
The children of the `` component will not be translated.
Its contents will never be passed to the General Translation API.
# gt: General Translation CLI tool: Auth
URL: https://generaltranslation.com/en-US/docs/cli/auth.mdx
---
title: Auth
description: Authenticate your project with General Translation
---
## Usage
```bash
npx gt auth
```
## Overview
Use this CLI command to generate an API key and project ID for your project.
This command will:
1. Prompt the user to sign in to the General Translation dashboard.
2. Generate an API key and project ID for your project.
3. Create a `.env.local` file in the root of your project and add it to your `.gitignore` file (if it doesn't already exist).
4. Add the API key and project ID to the `.env.local` file.
## Flags
| Parameter | Description | Type | Optional | Default |
| --- | --- | --- | --- | --- |
| `-c, --config ` | Path to the GT config file | `string` | `true` | `"gt.config.json"` |
| `-t, --key-type ` | Type of key to generate: `production`, `development`, or `all` | `string` | `true` | prompted interactively |
# gt: General Translation CLI tool: Branching
URL: https://generaltranslation.com/en-US/docs/cli/branching.mdx
---
title: Branching
description: Track translations separately for different git branches
---
## Overview
Branching allows you to track translations separately for different git branches in your project.
This is useful when you're working on feature branches that introduce new content or modify existing text, and you want to keep those translations isolated from your main branch until the feature is merged.
When branching is enabled, the CLI automatically detects your current git branch and associates translations with that branch.
Translations created on a feature branch won't affect your production translations until you merge.
Branching is a feature of the GT Cloud and requires a paid plan. If you attempt to create a non-default branch without a paid plan, the CLI will fall back to using the default branch.
---
## Usage
To enable branching, use the `--enable-branching` flag with the `translate` command:
```bash
npx gt translate --enable-branching
```
By default, the CLI will automatically detect your current git branch. If you want to specify a custom branch name instead:
```bash
npx gt translate --enable-branching --branch my-feature-branch
```
---
## Flags
| Flag | Description |
| ---------------------------- | ------------------------------------------------------------------------------------------------ |
| `--enable-branching` | Enable branching for the project. Required to use branch-based translation tracking. |
| `--branch ` | Specify a custom branch name instead of auto-detecting from git. |
| `--disable-branch-detection` | Disable automatic detection of branch relationships. Use only the manually specified branch. |
---
## How it works
When branching is enabled, the CLI performs the following:
1. **Detects the current branch**: Uses git to determine which branch you're currently on.
2. **Identifies the default branch**: Determines which branch is the default (usually `main` or `master`) by checking the remote HEAD reference.
3. **Tracks branch relationships**: Identifies branches that have been merged into the current branch (incoming branches) and the branch the current branch was checked out from (parent branch).
4. **Associates translations with branches**: All translations are tagged with the current branch, keeping them separate from other branches.
5. **Inherits translations from parent branches**: When you create a new branch, translations are automatically inherited from the parent branch, so they are not re-translated and you are not double-charged.
### Translation inheritance
When working on a feature branch, the CLI tracks:
- **Incoming branches**: Branches that have been merged into your current branch. This allows translations from merged branches to be incorporated.
- **Checked-out branch**: The branch your current branch was created from (typically the default branch). This allows your feature branch to inherit existing translations.
This means that when you create a new feature branch off `main`, your branch will have access to all the existing translations from `main`. Any new translations you create will be associated with your feature branch until it's merged.
After merging the feature branch back into `main`, the translations from the feature branch are automatically incorporated into `main`.
---
## Configuration
You can configure branching options in your `gt.config.json` file:
```json title="gt.config.json"
{
"branchOptions": {
"enabled": true,
"currentBranch": "my-feature-branch",
"autoDetectBranches": true,
"remoteName": "origin"
}
}
```
| Property | Description | Default |
| -------------------- | --------------------------------------------------------------------------- | ----------- |
| `enabled` | Enable branching for the project | `false` |
| `currentBranch` | Override the current branch name (instead of auto-detect) | `undefined` |
| `autoDetectBranches` | Automatically detect branch relationships (incoming and checked-out branches) | `true` |
| `remoteName` | The git remote name used for branch detection | `"origin"` |
CLI flags take precedence over config file options. For example, `--enable-branching` will override `branchOptions.enabled`, and `--disable-branch-detection` will override `branchOptions.autoDetectBranches`.
---
## Example workflow
Here's a typical workflow using branching:
1. **Create a feature branch**:
```bash
git checkout -b feature/new-landing-page
```
2. **Add new translatable content** to your feature branch.
3. **Translate with branching enabled**:
```bash
npx gt translate --enable-branching
```
The CLI detects you're on `feature/new-landing-page` and associates all new translations with that branch.
4. **Iterate on your feature** - any additional translations stay on your feature branch.
5. **Merge your feature branch** into `main`:
```bash
git checkout main
git merge feature/new-landing-page
```
6. **Run translate on main**:
```bash
npx gt translate --enable-branching
```
The CLI detects the translations from `feature/new-landing-page` and incorporates those translations into `main`.
---
## Troubleshooting
### Branch not detected
If the CLI cannot detect your current branch, you can specify it manually:
```bash
npx gt translate --enable-branching --branch my-branch
```
### Using a non-standard remote
If your git remote is not named `origin`, configure the remote name in your config:
```json title="gt.config.json"
{
"branchOptions": {
"remoteName": "upstream"
}
}
```
or use the `--remote-name` flag:
```bash
npx gt translate --enable-branching --remote-name upstream
```
### Disabling branch relationship detection
If you only want to use the current branch without tracking incoming or parent branches:
```bash
npx gt translate --enable-branching --branch my-branch --disable-branch-detection
```
# gt: General Translation CLI tool: Configure
URL: https://generaltranslation.com/en-US/docs/cli/configure.mdx
---
title: Configure
description: Configure your project's GT settings
---
## Usage
```bash
npx gt configure
```
## Overview
The `configure` command helps you configure your project's GT settings.
It will create a `gt.config.json` file in the root of your project.
The file will contain the following settings:
- `defaultLocale`: The default locale for your project.
- `locales`: An array of [supported locales](/docs/platform/supported-locales) for your project.
- `files`: This is an object that contains information about the content you want to translate.
For more specific information about the `gt.config.json` file, please see the [config docs](/docs/cli/reference/config).
# gt: General Translation CLI tool: Download
URL: https://generaltranslation.com/en-US/docs/cli/download.mdx
---
title: Download
description: How to download translations that were previously enqueued or staged
---
## Usage
```bash
npx gt download
```
**Note:** This command requires a production API key! Get one on the
[platform](https://generaltranslation.com/dashboard).
## Overview
The `gt download` command downloads completed translations that were previously sent for translation via [`gt enqueue`](/docs/cli/enqueue) or [`gt stage`](/docs/cli/stage).
The typical workflow is:
1. [`gt upload`](/docs/cli/upload) — upload source files to the General Translation platform
2. [`gt enqueue`](/docs/cli/enqueue) — enqueue the uploaded files for translation
3. **`gt download`** — download the completed translations
This separation is useful in CI/CD pipelines where each step happens in a different stage or job.
**For Production Use Only!**
This command is meant for production builds and **should not be used in development**.
Remember to specify your production API key (`GT_API_KEY`) and Project ID (`GT_PROJECT_ID`) in your environment variables.
## How it works
1. Reads your `gt.config.json` to determine the file configuration
2. If `stageTranslations` is enabled, reads the staged version data; otherwise, collects and hashes files to determine what to download
3. Polls the General Translation API for completed translations
4. Downloads and saves translation files to the output paths specified in your config
## Flags
The `download` command accepts the same flags as [`translate`](/docs/cli/translate#flags).
| Parameter | Description | Type | Optional | Default |
| ------------------------------- | -------------------------------------------------------------------------------------------------- | ---------- | -------- | ---------------------- |
| `--api-key` | Specify a production API key | `string` | `true` | |
| `--project-id` | Specify the project ID | `string` | `true` | |
| `--version-id` | Specify a version ID (by default, a hash of the content) | `string` | `true` | |
| `--config ` | Specify a path to the GT config file | `string` | `true` | `"gt.config.json"` |
| `--timeout` | The timeout for the request in seconds | `number` | `true` | `900` |
| `--new, --locales ` | Locales to translate your project into | `[string]` | `true` | |
| `--default-locale ` | The source locale for the project | `string` | `true` | `en` |
| `--dry-run` | Dry run the command | `flag` | `true` | `false` |
| `--force` | Force a download of all translations, overwriting local changes | `flag` | `true` | `false` |
| `--force-download` | Force a download of all translations, overwriting local changes | `flag` | `true` | `false` |
## Example: Split CI pipeline
```bash
# Stage 1: Upload source files
npx gt upload
# Stage 2: Enqueue translations
npx gt enqueue
# Stage 3: Download when ready
npx gt download
```
# gt: General Translation CLI tool: Enqueue
URL: https://generaltranslation.com/en-US/docs/cli/enqueue.mdx
---
title: Enqueue
description: How to enqueue translations without downloading them
---
## Usage
```bash
npx gt enqueue
```
**Note:** This command requires a production API key! Get one on the
[platform](https://generaltranslation.com/dashboard).
## Overview
The `gt enqueue` command enqueues previously uploaded files for translation, **without waiting for or downloading the results**.
The typical workflow is:
1. [`gt upload`](/docs/cli/upload) — upload source files to the General Translation platform
2. **`gt enqueue`** — enqueue the uploaded files for translation
3. [`gt download`](/docs/cli/download) — download the completed translations
This separation is useful in CI/CD pipelines where each step happens in a different stage or job.
**For Production Use Only!**
This command is meant for production builds and **should not be used in development**.
Remember to specify your production API key (`GT_API_KEY`) and Project ID (`GT_PROJECT_ID`) in your environment variables.
## How it works
1. Reads your `gt.config.json` to determine which files to translate
2. Identifies the previously uploaded files by their content hashes
3. Sends them to the General Translation API for translation
4. Exits immediately — does **not** wait for translations to complete
To download the translations once they're ready, run [`gt download`](/docs/cli/download).
## Flags
The `enqueue` command accepts the same flags as [`translate`](/docs/cli/translate#flags).
| Parameter | Description | Type | Optional | Default |
| ------------------------------- | -------------------------------------------------------------------------------------------------- | ---------- | -------- | ---------------------- |
| `--api-key` | Specify a production API key | `string` | `true` | |
| `--project-id` | Specify the project ID | `string` | `true` | |
| `--version-id` | Specify a version ID (by default, a hash of the content) | `string` | `true` | |
| `--config ` | Specify a path to the GT config file | `string` | `true` | `"gt.config.json"` |
| `--timeout` | The timeout for the request in seconds | `number` | `true` | `900` |
| `--new, --locales ` | Locales to translate your project into | `[string]` | `true` | |
| `--default-locale ` | The source locale for the project | `string` | `true` | `en` |
| `--dry-run` | Dry run the command | `flag` | `true` | `false` |
## Example: Split CI pipeline
```bash
# Stage 1: Upload source files
npx gt upload
# Stage 2: Enqueue translations
npx gt enqueue
# Stage 3: Download when ready
npx gt download
```
# gt: General Translation CLI tool: FAQs
URL: https://generaltranslation.com/en-US/docs/cli/faqs.mdx
---
title: FAQs
description: Frequently asked questions about the GT CLI tool
---
### Do I need an API key to use the CLI?
The [`translate`](/docs/cli/translate) command requires a production API key, which you can get for free at [generaltranslation.com](https://generaltranslation.com). The [`init`](/docs/cli/init) command can generate one for you during setup.
### When should I run `gt translate`?
Run it in your CI/CD pipeline **before** building your app for production. It should not be used during development — in development, use development API keys for on-demand translation instead.
### Can I use the CLI with libraries other than gt-next and gt-react?
Yes. The CLI can generate translations for third-party i18n libraries like [next-intl](https://next-intl.dev/) and [i18next](https://react.i18next.com/). It can also translate standalone JSON, Markdown, MDX, JS, and TS files.
### What file formats does the CLI support?
The CLI supports [JSON](/docs/cli/formats/json), [MDX](/docs/cli/formats/mdx), [HTML](/docs/cli/formats/html), [TypeScript/JavaScript](/docs/cli/formats/ts), [YAML](/docs/cli/formats/yaml), [PO/POT](/docs/cli/formats/po), [plain text](/docs/cli/formats/txt), and [GT's internal format](/docs/cli/formats/gt).
### Where do the translations go?
Depending on your configuration, translations are either uploaded to the GT CDN or saved locally in your project bundle. See [`save-local`](/docs/cli/save-local) for details on storing translations locally.
# gt: General Translation CLI tool: Generate Source Template
URL: https://generaltranslation.com/en-US/docs/cli/generate.mdx
---
title: Generate Source Template
description: How to generate a source template for your project
---
## Usage
```bash
npx gt generate
```
## Overview
The `gt generate` command generates a source file for your project for your default locale and supported locales.
The generated files are compatible with the [`gt-next`](/docs/next), [`gt-react`](/docs/react), and [`gt-react-native`](/docs/react-native) libraries, and are the same format used by the `translate` command.
After generating the source files, you can use [local translations](/docs/next/guides/local-tx) to serve the translations to your users.
This command is only useful if you are using your own translation service.
If you are using the General Translation API, you should use the [`translate`](/docs/cli/translate) command instead.
## Parameters
| Parameter | Description | Type | Optional | Default |
| ------------------------------- | -------------------------------------------------------------------------------------------------- | ---------- | -------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `--src ` | Space-separated list of glob patterns to match source files. Should be relative to root directory. | `[string]` | `true` | `[ 'src/**/*.{js,jsx,ts,tsx}', 'app/**/*.{js,jsx,ts,tsx}', 'pages/**/*.{js,jsx,ts,tsx}', 'components/**/*.{js,jsx,ts,tsx}', ]` |
| `--dictionary ` | Specify a path to the dictionary file | `string` | `true` | |
| `--tsconfig, --jsconfig ` | Specify a path to the TS or JS config file | `string` | `true` | |
| `--inline` | Include inline `` tags in addition to the dictionary | `boolean` | `true` | `true` |
| `--default-locale ` | The source locale for the project | `string` | `true` | `en` |
| `--ignore-errors` | Ignore errors and force translation for valid content | `flag` | `true` | `false` |
## Setup
First, run the `gt configure` command to configure your project's settings.
```bash
npx gt configure
```
Then, run the `gt generate` command to generate template files for your project.
```bash
npx gt generate
```
### Configuration file
Read more about the `gt.config.json` file [here](/docs/cli/reference/config).
# gt: General Translation CLI tool: Translation CLI
URL: https://generaltranslation.com/en-US/docs/cli.mdx
---
title: Translation CLI
description: Set up and translate your project with the General Translation command line tool
---
## Overview
The General Translation CLI tool (`gt`) lets you set up internationalization and automatically translate your project into any of the [supported languages](/docs/platform/supported-locales).
It works with [`gt-next`](/docs/next), [`gt-react`](/docs/react), [`gt-react-native`](/docs/react-native), and third-party i18n libraries like `next-intl` and `i18next`. You can also use it to translate standalone files (JSON, MDX, HTML, and more).
## Quickstart
### 1. Set up your project
```bash
npx gt@latest
```
This runs the setup wizard, which will:
- Install the necessary dependencies (e.g., `gt-next` or `gt-react`)
- Configure your framework (Next.js plugin, React provider, etc.)
- Create a `gt.config.json` with your locales and file settings
- Generate API credentials
### 2. Translate
```bash
npx gt translate
```
This translates your project using the General Translation API. Run it in your CI/CD pipeline **before** building for production.
**Note:** A production API key is required for the `translate` command. The setup wizard can generate one for you, or get one at [generaltranslation.com](https://generaltranslation.com).
That's it — two commands to go from a single-language project to a fully translated one.
## Commands
| Command | Description |
| --- | --- |
| [`npx gt@latest`](/docs/cli/init) | Run the setup wizard. Installs dependencies, configures your project, and generates credentials. |
| [`npx gt translate`](/docs/cli/translate) | Translate your project via the GT API. |
| [`npx gt configure`](/docs/cli/configure) | Update your project's GT settings (`gt.config.json`). |
| [`npx gt auth`](/docs/cli/auth) | Generate or refresh API credentials. |
| [`npx gt generate`](/docs/cli/generate) | Generate a translation data JSON file for standalone use. |
| [`npx gt upload`](/docs/cli/upload) | Upload source files and translations to the GT platform. |
| [`npx gt enqueue`](/docs/cli/enqueue) | Enqueue files for translation without downloading results. |
| [`npx gt download`](/docs/cli/download) | Download translations that were previously enqueued or staged. |
| [`npx gt stage`](/docs/cli/stage) | Stage translations for human review before publishing. |
| [`npx gt save-local`](/docs/cli/save-local) | Save local translation edits to the GT platform. |
## Guides
| Guide | Description |
| --- | --- |
| [Branching](/docs/cli/branching) | Track translations separately for different git branches. |
| [FAQs](/docs/cli/faqs) | Common questions about the CLI tool. |
## Supported formats
The CLI can translate files in a variety of formats:
[GT](/docs/cli/formats/gt) · [JSON](/docs/cli/formats/json) · [MDX](/docs/cli/formats/mdx) · [TypeScript/JavaScript](/docs/cli/formats/ts) · [YAML](/docs/cli/formats/yaml) · [PO/POT](/docs/cli/formats/po) · [HTML](/docs/cli/formats/html) · [Plain text](/docs/cli/formats/txt)
# gt: General Translation CLI tool: Setup Wizard
URL: https://generaltranslation.com/en-US/docs/cli/init.mdx
---
title: Setup Wizard
description: Run the GT setup wizard
---
## Usage
```bash
npx gt init
```
Use this command to run the GT setup wizard.
This command is the same as running `setup`, then running `configure`.
The wizard will:
1. Install the necessary dependencies for your project.
2. (If Next.js) Add the `withGTConfig` function to your `next.config.js` file and set up the `GTProvider` component.
3. Create a `gt.config.json` file in the root of your project.
4. Generate an API key and project ID for your project.
## Dependencies
The `init` command will install the following dependencies for your project:
- `gt-react` or `gt-next` (if your project is React-based)
- `gt` as a dev dependency (if not already installed)
## React-based projects
If your project is React-based, the wizard will help set up your project to use `gt-react` or `gt-next`.
If you are already using a different i18n library, you may need to manually set up your project.
See the [React docs](/docs/react) or the [Next.js docs](/docs/next) for more information.
Since the wizard is currently experimental, it is possible that it may not work for all React-based projects.
In these cases, you may need to manually set up your project.
If you encounter any issues, please let us know on [GitHub](https://github.com/generaltranslation/gt/issues).
This part of the wizard can also be run independently via `npx gt setup`.
## `gt.config.json`
The `init` command helps you configure your project's GT settings.
It will create a `gt.config.json` file in the root of your project.
The file will contain the following settings:
- `defaultLocale`: The default locale for your project.
- `locales`: An array of [supported locales](/docs/platform/supported-locales) for your project.
- `files`: This is an object that contains information about the content you want to translate.
For more specific information about the `gt.config.json` file, please see the [config docs](/docs/cli/reference/config).
This part of the wizard can also be run independently via `npx gt configure`.
## Credentials
The wizard will help you generate an API key and project ID for your project (if they are not already set up).
Please note that the API key and project ID are not required to use `gt-react` or `gt-next`.
The wizard will add the API key and project ID to your `.env.local` file.
If this file does not exist, the wizard will create it and add it to your `.gitignore` file.
This part of the wizard can also be run independently via `npx gt auth`.
# gt: General Translation CLI tool: Save Local Edits
URL: https://generaltranslation.com/en-US/docs/cli/save-local.mdx
---
title: Save Local Edits
description: How to save edits made to local translation files
---
## Usage
```bash
npx gt save-local
```
This command requires an API key. Get one on the
[platform](https://generaltranslation.com/dashboard).
## Overview
The `gt save-local` command saves any local edits you've made to translation files back to the General Translation platform. It does this by:
1. Reading your configured files from `gt.config.json`
2. Resolving the current git branch information
3. Comparing your local translation files against the latest downloaded server versions
4. Computing diffs for any changes you've made
5. Submitting those diffs to the General Translation platform
This command **does not enqueue any new translations**. It only syncs your local edits back to the platform.
This is useful when you or your team has manually edited translation files
locally and you want those changes reflected on the platform. For example, if
a translator has made corrections directly in JSON files.
## How it works
The CLI tracks which translations have been downloaded in a lock file. When you run `save-local`, it:
1. Identifies files that have changed since the last download by comparing content hashes
2. Fetches the original server content for those files
3. Generates unified diffs between the server version and your local version
4. Submits the diffs to the platform
Only files that have actually changed will be processed.
---
## Flags
| Parameter | Description | Type | Optional | Default |
| -------------- | ------------------------------- | -------- | -------- | ------------------ |
| `--api-key` | API key for General Translation | `string` | `true` | |
| `--project-id` | General Translation project ID | `string` | `true` | |
| `-c, --config` | Path to the GT config file | `string` | `true` | `"gt.config.json"` |
| `--publish` | Publish translations to the CDN | `flag` | `true` | `false` |
All of these parameters are optional if you have them configured via environment variables or in your `gt.config.json`.
Do not add your API key to the `gt.config.json` file! You should set it as an
environment variable instead. The CLI will automatically read `GT_API_KEY` if
it is set.
## Related commands
- [`gt translate`](/docs/cli/translate) - Translate your project and download translations
- [`gt translate --save-local`](/docs/cli/translate) - Save local edits before translating (combines both operations)
# gt: General Translation CLI tool: Stage
URL: https://generaltranslation.com/en-US/docs/cli/stage.mdx
---
title: Stage
description: How to stage your translations for review
---
## Overview
`gt stage` is a command that generates translations for your project and stages them for review.
This command is only useful if you've enabled human review on your project.
## Usage
Run this in your CI pipeline **before** you build your app for production.
```bash
npx gt stage
```
**Note:**
This command requires a production API key! Get one on the [platform](https://generaltranslation.com/dashboard).
The `gt stage` command works in the same way as the `translate` command, but instead of downloading the completed translations or publishing them to the CDN, it stages them for review.
After running `gt stage`, you should run `gt translate` to complete the process and download the translations (if configured to do so).
**For Production Use Only!**
This command is meant for production builds and **should not be used in development**.
Before running this command, please make sure you are on the branch that will be used for production.
Remember to also specify your production API key (`GT_API_KEY`) and Project ID (`GT_PROJECT_ID`) in your environment variables.
---
## Flags
| Parameter | Description | Type | Optional | Default |
|-----------------|--------------------------------------------------|---------|----------|-----------------|
| `--api-key` | Specify a production API key | `string` | `true` | |
| `--project-id` | Specify the project ID | `string` | `true` | |
| `--version-id` | Specify a version ID (by default, a hash of the content) | `string` | `true` | |
| `--config `| Specify a path to the GT config file | `string` | `true` | `"gt.config.json"` |
| `--tsconfig, --jsconfig `| Specify a path to the TS or JS config file | `string` | `true` | |
| `--src ` | Space-separated list of glob patterns to match source files. Should be relative to root directory. | `[string]` | `true` | `[ 'src/**/*.{js,jsx,ts,tsx}', 'app/**/*.{js,jsx,ts,tsx}', 'pages/**/*.{js,jsx,ts,tsx}', 'components/**/*.{js,jsx,ts,tsx}', ]` |
| `--dictionary ` | Specify a path to the dictionary file | `string` | `true` | |
| `--inline` | Include inline `` tags in addition to the dictionary | `boolean` | `true` | `true` |
| `--timeout` | The timeout for the translation request in seconds | `number` | `true` | `900` |
| `--new, --locales `| Locales to translate your project into | `[string]` | `true` | |
| `--default-locale `| The source locale for the project | `string` | `true` | `en` |
| `--ignore-errors` | Ignore errors and force translation for valid content | `flag` | `true` | `false` |
| `--tag [value]` | Tag this translation run (auto-resolves from git if no value provided) | `string` | `true` | |
| `-m, --message ` | Message to attach to the translation tag | `string` | `true` | |
| `--dry-run` | Dry run the command | `flag` | `true` | `false` |
All of these parameters are optional.
Do not add your API key to the `gt.config.json` file!
You should set it as an environment variable instead. The CLI will automatically read `GT_API_KEY` if it is set.
There are a few key parameters:
| Parameter | Description |
|-----------------|--------------------------------------------------|
| `--dry-run` | This flag will cause the CLI to parse and validate your project, but will not communicate with the GT API. This is useful for validating your codebase.
| `--api-key` | Unless you are using `--dry-run`, you must provide a production API key.
| `--project-id` | Similarly, unless you are using `--dry-run`, you must provide a project ID.
| `--new, --locales ` | Locales to translate your project into. These will be appended to the locales specified in your `gt.config.json` file.
### Configuration file
When running `gt stage`, the CLI will automatically add the `stageTranslations : true` property to your `gt.config.json` file.
This property ensures that if `translate` is run without first running `stage` for a specific deployment version,
the CLI tool will error and exit.
# gt: General Translation CLI tool: Translate
URL: https://generaltranslation.com/en-US/docs/cli/translate.mdx
---
title: Translate
description: How to translate your project
---
## Usage
```bash
npx gt translate
```
**Important:** Run this in your CI pipeline **before** you build your app for production.
## Overview
The `gt translate` command translates your project by reading your `gt.config.json` file to determine which files to translate.
If you are using [`gt-next`](/docs/next), [`gt-react`](/docs/react), or [`gt-react-native`](/docs/react-native), it will also search your project's source code for inline content (such as `` components and `useGT` hooks) and generate the necessary translation files.
Additionally, it includes content from the dictionary file (if one is provided).
This command is the primary way of using the General Translation API and related services.
**For production use only:** This command is meant for production builds and **should not be used in development**.
Before running this command, make sure you are on the branch that will be used for production.
Set your production API key (`GT_API_KEY`) and project ID (`GT_PROJECT_ID`) as environment variables.
**Note:** A production API key is required. Get one for free at [generaltranslation.com](https://generaltranslation.com/dashboard), or run the [setup wizard](/docs/cli/init) to generate one.
### Translate your project [#translate]
```bash
npx gt translate
```
The `translate` command reads your `gt.config.json` to determine which files to translate, searches your project's source code for translatable content, and generates the necessary translation files.
Translations are automatically saved to your codebase.
See the [config docs](/docs/cli/reference/config#files) for more details.
{/* These links point to our own SDK docs intentionally — we want to show how our CLI handles these libraries, not link to the external library sites */}
**Auto-detection:** If you are using [`next-intl`](/docs/next), [`react-i18next`](/docs/react), or
[`next-i18next`](/docs/react-native), the CLI tool will automatically detect
your i18n library by reading your `package.json` file, and will translate your
JSONs while respecting your i18n library's syntax.
### Validate without translating [#validate]
```bash
npx gt translate --dry-run
```
If you are using [`gt-next`](/docs/next), [`gt-react`](/docs/react), or [`gt-react-native`](/docs/react-native), you can use this to validate your project's `` components and dictionary file without generating translations.
---
## Flags
| Parameter | Description | Type | Default |
| --- | --- | --- | --- |
| `--api-key` | Specify a production API key | `string` | |
| `--project-id` | Specify the project ID | `string` | |
| `--version-id` | Specify a version ID (by default, a hash of the content) | `string` | |
| `--config ` | Specify a path to the GT config file | `string` | `"gt.config.json"` |
| `--tsconfig, --jsconfig ` | Specify a path to the TS or JS config file | `string` | |
| `--src ` | Space-separated glob patterns for source files (relative to root) | `[string]` | `['src/**/*.{js,jsx,ts,tsx}', 'app/**/*.{js,jsx,ts,tsx}', 'pages/**/*.{js,jsx,ts,tsx}', 'components/**/*.{js,jsx,ts,tsx}']` |
| `--dictionary ` | Specify a path to the dictionary file | `string` | |
| `--inline` | Include inline `` tags in addition to the dictionary | `boolean` | `true` |
| `--timeout` | Timeout for the translation request in seconds | `number` | `900` |
| `--new, --locales ` | Locales to translate into (appended to `gt.config.json` locales) | `[string]` | |
| `--default-locale ` | The source locale for the project | `string` | `en` |
| `--ignore-errors` | Ignore errors and force translation for valid content | `flag` | `false` |
| `--dry-run` | Validate without translating | `flag` | `false` |
| `--force` | Force retranslation of all content | `flag` | `false` |
| `--force-download` | Force download of all translations | `flag` | `false` |
| `--save-local` | Detect and save local edits before enqueuing translations | `flag` | `false` |
| `--enable-branching` | Enable branching for the project | `flag` | `false` |
| `--branch ` | Specify a custom branch name for translations | `string` | |
| `--disable-branch-detection` | Disable automatic branch detection | `flag` | `false` |
| `--tag [value]` | Tag this translation run (auto-resolves from git if no value provided) | `string` | |
| `-m, --message ` | Message to attach to the translation tag | `string` | |
| `--publish` | Publish translations to the CDN after translating | `flag` | `false` |
| `--remote-name ` | Specify a custom remote name for branch detection | `string` | `"origin"` |
**Security:** Do not add your API key to the `gt.config.json` file! Set it as an environment variable instead. The CLI automatically reads `GT_API_KEY` if set.
### Key flags
| Flag | Description |
| --- | --- |
| `--dry-run` | Parse and validate your project without communicating with the GT API. Useful for validating your codebase. |
| `--force` | Retranslate all content, overwriting existing translations. Any local changes will be lost. You will be charged for new translations. |
| `--force-download` | Re-download all translations, overwriting local changes. Does not retranslate. |
| `--save-local` | Detect and save local edits to translation files before enqueuing. See [`save-local`](/docs/cli/save-local). |
| `--enable-branching` | Track translations separately for different git branches. See [branching](/docs/cli/branching). |
| `--tag` | Tag a translation run with a human-readable identifier for version tracking. See [tagging](#tagging). |
| `-m, --message` | Attach a descriptive message to a translation tag. See [tagging](#tagging). |
| `--publish` | Publish translations to the CDN for runtime loading. See [publishing to the CDN](#publishing-to-the-cdn). |
### Configuration file
When running the CLI for the first time, it will attempt to create a `gt.config.json` file in the root of your project. Read more about configuration [here](/docs/cli/reference/config).
## Important tips
### Content sources
The `translate` command recursively searches for translatable content in your project.
By default, it searches in the following directories:
- `./src`
- `./app`
- `./pages`
- `./components`
You can specify alternate directories with the `--src` flag or by modifying the `src` property in your [`gt.config.json`](/docs/cli/reference/config).
### Overwriting translations
By default, the CLI will not overwrite local translation changes unless the source content has changed.
To retranslate content that has already been translated, use `--force`.
**Caution:** `--force` will **overwrite all existing translations and generate new ones**. Any local changes will be lost. You will be charged for new translations.
To re-download translations without retranslating, use `--force-download`.
**Caution:** `--force-download` will overwrite local translation changes and fetch the most recent translations. It will not retranslate any content.
### Tagging [#tagging]
Use the `--tag` and `-m` flags to label translation runs with human-readable identifiers, making it easier to track and identify versions in the dashboard.
#### Tag with a custom identifier
```bash
npx gt translate --tag v2.1.0
```
#### Tag with a custom identifier and message
```bash
npx gt translate --tag v2.1.0 -m "Added checkout page translations"
```
#### Auto-tag from git
Pass `--tag` without a value to automatically use the current git commit hash as the tag id and the commit message as the tag message:
```bash
npx gt translate --tag
```
You can override the commit message with a custom one:
```bash
npx gt translate --tag -m "Release 2.1 translations"
```
#### Message-only tagging
If you pass `-m` without `--tag`, a tag is auto-generated from the current git commit hash (or a random identifier if not in a git repo):
```bash
npx gt translate -m "Weekly translation update"
```
Tagging is non-blocking — if tag creation fails, the translation run continues normally.
### Publishing to the CDN [#publishing-to-the-cdn]
By default, `gt translate` saves translation files locally to your codebase. Use the `--publish` flag to also publish translations to the General Translation CDN, enabling runtime translation loading without bundling files into your app.
```bash
npx gt translate --publish
```
This is useful for `gt-next` projects that load translations from the CDN at runtime instead of from local files.
**CDN must be enabled:** Before using `--publish`, enable CDN in your project settings at [generaltranslation.com/dashboard](https://generaltranslation.com/dashboard). If CDN is not enabled, the command will translate successfully but fail to publish with a warning.
You can combine `--publish` with local file output — translations will be saved locally _and_ published to the CDN:
```bash
npx gt translate --publish
```
### Dictionary file
The `translate` command automatically detects the dictionary file in your project.
By default, it looks for a file named `dictionary.[json|ts|js]` in:
- `./src`
- `./`
You can specify an alternate dictionary file with the `--dictionary` flag or by modifying the `dictionary` property in your [`gt.config.json`](/docs/cli/reference/config).
# gt: General Translation CLI tool: Upload
URL: https://generaltranslation.com/en-US/docs/cli/upload.mdx
---
title: Upload
description: How to upload source files and translations to the General Translation platform
---
## Usage
```bash
npx gt upload
```
**Note:** This command requires a production API key! Get one on the
[platform](https://generaltranslation.com/dashboard).
## Overview
The `gt upload` command uploads your project's source files and any existing translations to the General Translation platform. This syncs your local files with the platform so they can be managed, enqueued for translation, and tracked.
The typical workflow for split CI/CD pipelines is:
1. **`gt upload`** — upload source files to the General Translation platform
2. [`gt enqueue`](/docs/cli/enqueue) — enqueue the uploaded files for translation
3. [`gt download`](/docs/cli/download) — download the completed translations
**For Production Use Only!**
This command is meant for production builds and **should not be used in development**.
Remember to specify your production API key (`GT_API_KEY`) and Project ID (`GT_PROJECT_ID`) in your environment variables.
## How it works
1. Reads your `gt.config.json` to determine which files to upload
2. Collects all translatable source files (JSON, YAML, Markdown, MDX, etc.)
3. Hashes each file to generate a `fileId` (based on path) and `versionId` (based on content)
4. Queries the General Translation API to determine which files are new or changed
5. Detects file moves (same content, different path) and preserves existing translations
6. Uploads new and changed source files to the platform
7. If existing translation files are found locally, uploads those as well
## Flags
The `upload` command accepts the same flags as [`translate`](/docs/cli/translate#flags).
| Parameter | Description | Type | Optional | Default |
| ------------------------------- | -------------------------------------------------------------------------------------------------- | ---------- | -------- | ---------------------- |
| `--api-key` | Specify a production API key | `string` | `true` | |
| `--project-id` | Specify the project ID | `string` | `true` | |
| `--version-id` | Specify a version ID (by default, a hash of the content) | `string` | `true` | |
| `--config ` | Specify a path to the GT config file | `string` | `true` | `"gt.config.json"` |
| `--new, --locales ` | Locales to translate your project into | `[string]` | `true` | |
| `--default-locale ` | The source locale for the project | `string` | `true` | `en` |
| `--dry-run` | Dry run the command | `flag` | `true` | `false` |
| `--timeout` | The timeout for the request in seconds | `number` | `true` | `600` |
## Example: Split CI pipeline
```bash
# Stage 1: Upload source files
npx gt upload
# Stage 2: Enqueue translations
npx gt enqueue
# Stage 3: Download when ready
npx gt download
```
# gt: General Translation CLI tool: Validate
URL: https://generaltranslation.com/en-US/docs/cli/validate.mdx
---
title: Validate
description: How to validate your project for translation errors
---
## Usage
```bash
npx gt validate
```
## Overview
The `gt validate` command scans your project for inline content (such as `` components and `useGT` hooks) and dictionary entries, then checks for syntax errors or issues that would prevent successful translation.
Unlike [`gt translate`](/docs/cli/translate), this command does **not** communicate with the General Translation API. It only performs local validation, making it safe to run at any time — in development, CI, or before a production build.
This command is available for projects using [`gt-next`](/docs/next), [`gt-react`](/docs/react), [`gt-react-native`](/docs/react-native), or [`gt-tanstack-start`](/docs/tanstack-start).
### Validate the entire project [#validate-project]
```bash
npx gt validate
```
This scans your source directories and dictionary file (if configured) for translatable content and reports any errors or warnings.
### Validate specific files [#validate-files]
```bash
npx gt validate src/components/Header.tsx src/pages/Home.tsx
```
You can pass one or more file paths as arguments to validate only those files instead of the entire project.
## What it checks
- **Inline content:** Scans source files for `` components, `useGT` hooks, and other inline translation patterns.
- **Dictionary entries:** Validates dictionary files for correct syntax.
- **Syntax errors:** Reports any issues that would cause `gt translate` or `gt stage` to fail.
If validation succeeds, you'll see a summary like:
```
Success! Found 12 translatable entries for gt-next.
```
If there are errors, the command will list them and exit with a non-zero status code, making it suitable for use in CI pipelines.
---
## Flags
| Parameter | Description | Type | Optional | Default |
|-----------------|--------------------------------------------------|---------|----------|-----------------|
| `-c, --config ` | Specify a path to the GT config file | `string` | `true` | `"gt.config.json"` |
| `--tsconfig, --jsconfig ` | Specify a path to the TS or JS config file | `string` | `true` | |
| `--dictionary ` | Specify a path to the dictionary file | `string` | `true` | |
| `--src ` | Space-separated list of glob patterns to match source files | `[string]` | `true` | `['src/**/*.{js,jsx,ts,tsx}', 'app/**/*.{js,jsx,ts,tsx}', 'pages/**/*.{js,jsx,ts,tsx}', 'components/**/*.{js,jsx,ts,tsx}']` |
| `--inline` | Include inline content in validation | `boolean` | `true` | `true` |
All of these parameters are optional.
# Locadex: Localization AI Agent: Auto-merge Pull Requests
URL: https://generaltranslation.com/en-US/docs/locadex/auto-merge.mdx
---
title: Auto-merge Pull Requests
description: Configure Locadex to automatically merge pull requests
---
Auto-merge eliminates manual PR review for Locadex-generated pull requests. When enabled, PRs created by Locadex merge automatically without requiring your approval.
This applies to all PRs Locadex creates, including:
- Continuous i18n
- Update Locales
- Translation redeployments
_This does not apply to Setup or Re-run Setup PRs._
For Mintlify projects, auto-merge is enabled by default.
## Enable auto-merge
Navigate to the Locadex page in your dashboard and toggle auto-merge under "Run Configuration":

**Make sure to click "Save" after toggling auto-merge** to apply your changes.
**Note**: The Auto-merge toggle only appears when "Locadex Action" is set to "Create pull request".
## Bypass branch protection rules
If your default branch has protection rules, Locadex will continue creating PRs but cannot merge them automatically. Configure Locadex to bypass branch protection:
### Step 1: Open repository rulesets
In your GitHub repository settings, select "Rulesets" from the Rules section.
### Step 2: Identify blocking rules
Find rules preventing automatic merges. Common blockers include:
- "Require a pull request before merging"
- Required status checks
- Required review approvals

**Note**: Multiple rules may need updating.
### Step 3: Add bypass permissions
Click the rule blocking auto-merge, then:
1. Click "Add Bypass"
2. Select "Locadex Agent" from the dropdown

### Step 4: Save changes
Click "Save" at the bottom of the page to apply your changes.
**Make sure to click "Save"** — this step is easy to miss.
# Locadex: Localization AI Agent: FAQs
URL: https://generaltranslation.com/en-US/docs/locadex/faqs.mdx
---
title: FAQs
description: Frequently asked questions about Locadex
---
### What is Locadex?
Locadex is an AI agent that automates internationalization and translation for your project. Once installed, it monitors your repository and keeps translations up to date as your code changes.
### How does Locadex integrate with my workflow?
Locadex connects to your GitHub repository and can run automatically when it detects changes, or manually from the dashboard. It opens pull requests with translation updates that you can review before merging.
### Does Locadex work with monorepos?
Yes. See the [monorepos guide](/docs/locadex/monorepos) for configuration details.
### What frameworks does Locadex support?
Locadex currently has guides for [Next.js](/docs/locadex/next) and [Mintlify](/docs/locadex/mintlify). It can also work with other setups that use the GT CLI.
### Can I control which translations Locadex updates?
Yes. You can configure Locadex through your project settings on the dashboard and use [auto-merge](/docs/locadex/auto-merge) settings to control how translation PRs are handled.
# Locadex: Localization AI Agent: Locadex VM Image
URL: https://generaltranslation.com/en-US/docs/locadex/image.mdx
---
title: Locadex VM Image
description: Environment and tooling included in Locadex VM images
---
Locadex runs in an isolated VM image with the runtime and tooling it needs to inspect, update, and validate your repository.
## Runtime
The image includes:
- Node.js 24 (from `node:24-slim`)
- npm
- Bun `1.3.9`
## Environment variables
Configure environment variables in your Locadex settings under **Environment variables**.
Environment variables are encrypted at rest and can only be accessed by the Locadex runtime.
## Available commands
The image includes common command-line tools used for repository inspection, dependency installation, and code changes:
- `git`
- `wget`
- `curl`
- `tar`
- `build-essential`
- `python3`
- `python3-venv`
- `python3-pip`
- `ripgrep`
- `jq`
- `ca-certificates`
- `unzip`
## Preset linters
Locadex can run supported preset linters without modifying your package manifest or lockfile.
Available linter commands:
- `biome`
- `eslint`
- `ultracite`
## Project dependencies
The image does not install your project's dependencies ahead of time. If you need to install dependencies, you can do so using the pre-process and post-process commands.
The image does not include browser runtimes or Docker-in-Docker support.
# Locadex: Localization AI Agent: Locadex Agent
URL: https://generaltranslation.com/en-US/docs/locadex.mdx
---
title: Locadex Agent
description: Get started with Locadex, the automated internationalization engineer
---
**Locadex is an AI agent built to handle 100% of internationalization (i18n) and translation work for you.**
It takes 5 minutes to install, after which your project will be configured and translated into any language you choose automatically.
See guides for:
- [Mintlify](/docs/locadex/mintlify)
- [Next.js](/docs/locadex/next)
# Locadex: Localization AI Agent: Locadex for Mintlify
URL: https://generaltranslation.com/en-US/docs/locadex/mintlify.mdx
---
title: Locadex for Mintlify
description: Automate translation for your Mintlify docs
---
**Locadex is an AI agent built to handle 100% of internationalization (i18n) and translation work for you.**
It takes 5 minutes to install, after which your Mintlify docs will be configured and translated into all the languages you choose automatically.
Locadex:
- Sets up i18n routing and redirects in your docs
- Translates markdown files, code blocks, and snippets in context
- Continuously translates as you push new content
### Step 1: Sign into the General Translation Dashboard
Sign into the General Translation [Dashboard](https://dash.generaltranslation.com).

### Step 2: Connect GitHub
Navigate to the [Locadex](https://dash.generaltranslation.com) section in your dashboard and click "Connect GitHub".
You'll be redirected to GitHub to authorize the connection.

### Step 3: Install the GitHub app
Choose which repositories to give Locadex access to:

Click "Install" to complete the GitHub app installation.
### Step 4: Link repository to project
You'll be directed back to your General Translation project, where you can select the repository with your Mintlify docs.

### Step 5: Configure settings
On the configuration screen, set up:
- **Which languages do you need?**: The languages you want the docs to be available in
- **Default locale**: The language you originally wrote the docs in

### Step 6: Complete installation
Click "Install" to activate Locadex for your repository:

### Step 7: Review the PR
Locadex will create a pull request on your main branch. This may take a few minutes to complete.

Review the PR and merge it to complete your i18n setup.
### Step 8: Continuous internationalization
After the initial setup PR is merged, Locadex monitors your main branch for commits and updates translations as needed.

### Supported frameworks
Currently, Locadex only supports Mintlify and [Next.js App router](/docs/locadex) apps.
### Troubleshooting
When you have Locadex installed across multiple GitHub accounts or organizations, the dashboard will display a list of all of the accounts and organizations.
Connecting to an account or organization will link that account to your current GT org.

# Locadex: Localization AI Agent: Monorepo Support
URL: https://generaltranslation.com/en-US/docs/locadex/monorepos.mdx
---
title: Monorepo Support
description: How to use Locadex on a Next.js app within a monorepo
---
To use Locadex with a monorepo, specify your app directory on the dashboard in the Locadex settings.
For example, if your Next.js app is at the `/apps/dashboard` filepath, make sure `/apps/dashboard` is the Locadex working directory.

# Locadex: Localization AI Agent: Locadex for Next.js App Router
URL: https://generaltranslation.com/en-US/docs/locadex/next.mdx
---
title: Locadex for Next.js App Router
description: Automate translation for your Next.js app
---
Translating your Next.js app into French 🇫🇷, Spanish 🇪🇸, Japanese 🇯🇵, or any other language is painful and time-consuming.
**Locadex is an AI agent built to handle 100% of the internationalization (i18n) work for you.**
It takes 5 minutes to install.
{/*  */}
Locadex:
- Configures your project to use the gt-next i18n library
- Modifies your React components and strings to support multilingual content
- Translates your app into as many languages as you need
- Continuously internationalizes and translates as you push new content
### Step 1: Sign into the General Translation Dashboard
Go to your [Dashboard](https://dash.generaltranslation.com) and sign in to your account.
### Step 2: Connect GitHub
1. Navigate to the GitHub integration section in your dashboard
2. Click "Connect GitHub" to link your GitHub account
3. You'll be redirected to GitHub to authorize the connection
### Step 3: Install the GitHub app
1. After connecting GitHub, you'll be redirected to install the Locadex GitHub app
2. Choose which repositories to give Locadex access to:
- Install on all repositories, or
- Select specific repositories
3. Click "Install" to complete the GitHub app installation
### Step 4: Link repository to project
1. Back in your GT dashboard, select the repository you want to internationalize
2. This connects your repo to your translation settings and target languages
3. Only one repository can be linked to a project, but you can create multiple projects, each with a different repository
### Step 5: Configure settings
On the configuration screen, set up:
- **Target Languages**: Choose which locales to translate into

### Step 6: Complete installation
1. Review your configuration settings
2. Click "Install" to activate Locadex for your repository
3. You'll be taken to an overview page showing your connected GitHub repository
## What happens next?
### Initial setup
Once you complete the installation:
1. **Immediate PR Creation**: Locadex will create a pull request on your main branch
2. **Full Setup**: This PR runs the complete Locadex setup command that:
- Installs the GT libraries
- Configures your project for internationalization
- Sets up the translation infrastructure
3. **Review & Merge**: Review the PR and merge it to complete your i18n setup
### Continuous internationalization
After the initial setup is merged:
1. Locadex monitors your main or specified branch for pull requests
2. When you push new code with translatable content, wait for Locadex to add its commit to the PR
3. Once Locadex commits to the PR, it is safe to merge -- your new code is internationalized
4. Your app stays translated without manual intervention
## Monitoring your repository


### Dashboard status
In the dashboard, you can monitor:
- **Repository Status**: Active monitoring indicator
- **Configuration**: Current settings and target languages
### GitHub app
- **Status checks**: Locadex adds status updates to pull requests
- **Check runs**: GitHub shows Locadex processing status
## Troubleshooting
### Common issues
**Locadex not creating PRs**
- Verify the GitHub app has repository access
- Check that commits contain translatable content
**Configuration changes needed**
- Update branch settings in your GT dashboard
- Changes apply to new commits after the update
# Linting Rules for gt-next: gt-next Lint
URL: https://generaltranslation.com/en-US/docs/next-lint.mdx
---
title: gt-next Lint
description: ESLint plugin for gt-next components.
---
This is in alpha. Subject to changes.
ESLint plugin that catches common translation errors in gt-next components.
## Installation
```bash
npm install --save-dev @generaltranslation/gt-next-lint
```
## Configuration
Add to your `eslint.config.mjs`:
```javascript
import gtNext from "@generaltranslation/gt-next-lint";
export default [
{
plugins: { 'gt-next': gtNext },
rules: {
'gt-next/no-dynamic-jsx': 'warn',
'gt-next/no-dynamic-string': 'warn',
},
},
];
```
## Rules
### `no-dynamic-jsx`
Wraps dynamic content in `` components with variable components.
```jsx
// ❌ Wrong
Hello {userName}!
// ✅ Correct
Hello {userName} !
```
### `no-dynamic-string`
Only allows string literals in translation functions.
```jsx
const gt = useGT();
// ❌ Wrong
gt(`Hello ${name}`)
gt('Hello ' + name)
// ✅ Correct
gt('Hello, {name}!', { name })
```
## Supported components
- `` - Variables
- `` - Dates
- `` - Numbers
- `` - Currency
## Supported functions
- `useGT` - Client translations
- `getGT` - Server translations
## Configuration presets
The plugin ships with a `recommended` config preset:
```javascript
import gtNext from "@generaltranslation/gt-next-lint";
export default [
gtNext.configs.recommended,
];
```
This enables both `no-dynamic-jsx` and `no-dynamic-string` as warnings.
# gt-next: General Translation Next.js SDK: FAQs
URL: https://generaltranslation.com/en-US/docs/next/faqs.mdx
---
title: FAQs
description: Frequently asked questions about gt-next
---
### What happens if there are missing translations in production?
If a translation for some content is missing in production, gt-next automatically falls back to the original source text. Your app will still render correctly — users will just see the default language for that piece of content.
### Why do I have to install the CLI tool?
The CLI tool parses the content inside all `` components and generates translations for that content in advance, so that all the translations are ready when your app is deployed to production.
In development, you don't need it because you can use development API keys to translate on demand.
### Where does the `` component get its translations?
`` can load translations from anywhere depending on how you've configured the library:
- If you have a project ID, the library can hit a free CDN
- It can store translations locally in your bundle
- It can do a mix of the two
See the [loadTranslations docs](/docs/next/api/config/load-translations) for more details.
During development, the `` component hits an API which uses a small AI model to create temporary translations so you can see them hot-reload as you write. These translations aren't stored anywhere — they're just served back to the app.
In production, `` won't do this, so your API keys are never exposed to the client.
### Does AI translation work with dynamic content and variables?
The `` component doesn't support translating dynamic content and variables directly, because the translations could potentially change with every re-render. However, you can still include dynamic content inside a `` by wrapping it with ``, ``, or `` components. This is similar to how other libraries handle string interpolation.
gt-next also has a [``](/docs/next/api/components/tx) server-side component which translates content at runtime and supports dynamic content, but it requires an API key.
### Can I deploy my app without depending on GT servers?
Yes. You can do the translations yourself, then load them from your own bundle or your own CDN. See the [loadTranslations docs](/docs/next/api/config/load-translations) for details on loading translations from local files.
### Why do I get `ReferenceError: TextEncoder is not defined` in Jest?
`jest-environment-jsdom` uses an older version of jsdom that doesn't include `TextEncoder`. GT libraries use it internally for hashing. This will resolve itself once Jest updates its jsdom dependency (newer jsdom versions already support `TextEncoder`), but in the meantime you can polyfill it with a setup file:
```js title="jest.setup.js"
const { TextEncoder, TextDecoder } = require('util');
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;
```
Then add it to your Jest config:
```json title="jest.config.json"
{
"setupFiles": ["./jest.setup.js"]
}
```
### How do I migrate from i18next or next-intl?
See the [migration guide](/docs/next/guides/migration) for step-by-step instructions on migrating from other i18n libraries.
# gt-next: General Translation Next.js SDK: Next.js Quickstart
URL: https://generaltranslation.com/en-US/docs/next.mdx
---
title: Next.js Quickstart
description: Add multiple languages to your Next.js app in under 10 minutes
---
By the end of this guide, your Next.js app will display content in multiple languages, with a language switcher your users can interact with.
**Prerequisites:**
- A Next.js app using the **App Router** (Next.js 13+)
- Node.js 18+
**Want automatic setup?** Run `npx gt@latest` to configure everything with the [Setup Wizard](/docs/cli/init). This guide covers manual setup.
---
## Step 1: Install the packages
`gt-next` is the library that powers translations in your app. `gt` is the CLI tool that prepares translations for production.
```bash
npm i gt-next
npm i -D gt
```
```bash
yarn add gt-next
yarn add --dev gt
```
```bash
bun add gt-next
bun add --dev gt
```
```bash
pnpm add gt-next
pnpm add --save-dev gt
```
---
## Step 2: Configure your Next.js config
`gt-next` uses a Next.js plugin called **`withGTConfig`** to set up internationalization at build time. Wrap your existing Next.js config with it:
```ts title="next.config.ts"
import { withGTConfig } from 'gt-next/config';
const nextConfig = {};
export default withGTConfig(nextConfig);
```
This plugin reads your translation settings and wires everything together behind the scenes. No other changes to your Next.js config are needed.
---
## Step 3: Create a translation config file
Create a **`gt.config.json`** file in your project root. This tells the library which languages you support:
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["es", "fr", "ja"],
"files": {
"gt": {
"output": "public/_gt/[locale].json"
}
}
}
```
- **`defaultLocale`** — the language your app is written in (your source language).
- **`locales`** — the languages you want to translate into. Pick any from the [supported locales list](/docs/platform/supported-locales).
- **`files.gt.output`** — where the CLI saves translation files. `[locale]` is replaced with each language code (e.g., `public/_gt/es.json`).
Add `public/_gt/` to your **`.gitignore`** — these files are generated, not hand-written:
```txt title=".gitignore"
public/_gt/
```
---
## Step 4: Add a load function for local translations
Create a **`loadTranslations`** file in your `src/` directory (or project root). This tells `gt-next` how to load the translation files generated by the CLI:
```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
const translations = await import(`../public/_gt/${locale}.json`);
return translations.default;
}
```
`withGTConfig` automatically detects a `loadTranslations.[js|ts]` file in your `src/` directory or project root — no additional configuration needed.
**Why local translations?** Local translations are bundled with your app, so they load instantly with no reliance on external services. See the [Local Translation Storage guide](/docs/next/guides/local-tx) for more details and trade-offs.
---
## Step 5: Add the GTProvider to your layout
The **`GTProvider`** component gives your entire app access to translations. It must wrap your app at the root layout level:
```tsx title="app/layout.tsx"
import { GTProvider } from 'gt-next';
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
{children}
);
}
```
`GTProvider` is a **server component** — it loads translations on the server and passes them down to your client components.
---
## Step 6: Mark content for translation
Now, wrap any text you want translated with the **``** component. `` stands for "translate":
```tsx title="app/page.tsx"
import { T } from 'gt-next';
export default function Home() {
return (
Welcome to my app
This content will be translated automatically.
);
}
```
You can wrap as much or as little JSX as you want inside ``. Everything inside it — text, nested elements, even formatting — gets translated as a unit.
---
## Step 7: Add a language switcher
Drop in a **``** so users can change languages:
```tsx title="app/page.tsx"
import { T, LocaleSelector } from 'gt-next';
export default function Home() {
return (
Welcome to my app
This content will be translated automatically.
);
}
```
`LocaleSelector` renders a dropdown populated with the languages from your `gt.config.json`.
---
## Step 8: Set up environment variables (optional)
To see translations in development, you need API keys from General Translation. These enable **on-demand translation** — your app translates content in real time as you develop.
Create a **`.env.local`** file:
```bash title=".env.local"
GT_API_KEY="your-api-key"
GT_PROJECT_ID="your-project-id"
```
Get your free keys at [dash.generaltranslation.com](https://dash.generaltranslation.com/signup) or by running:
```bash
npx gt auth
```
For development, use a key starting with `gtx-dev-`. Production keys (`gtx-api-`) are for CI/CD only.
Never expose `GT_API_KEY` to the browser or commit it to source control.
Yes. Without API keys, `gt-next` works as a standard i18n library. You won't get on-demand translation in development, but you can still:
- Provide your own translation files manually
- Use all components (``, ``, `LocaleSelector`, etc.)
- Run `npx gt generate` to create translation file templates, then translate them yourself
---
## Step 9: See it working
Start your dev server:
```bash
npm run dev
```
```bash
yarn dev
```
```bash
bun dev
```
```bash
pnpm dev
```
Open [http://localhost:3000](http://localhost:3000) and use the language dropdown to switch languages. You should see your content translated.
In development, translations happen on-demand — you may see a brief loading state the first time you switch to a new language. In production, translations are pre-generated and load instantly.
---
## Step 10: Translate strings (not just JSX)
For plain strings — like `placeholder` attributes, `aria-label` values, or `alt` text — use the **`useGT`** hook. It works in both server and client components:
```tsx title="app/contact/page.tsx"
import { useGT } from 'gt-next';
export default function ContactPage() {
const gt = useGT();
return (
);
}
```
If you prefer `async/await` in server components, import `getGT` from `gt-next/server`:
```tsx
import { getGT } from 'gt-next/server';
export default async function Page() {
const gt = await getGT();
return {gt('Hello')}
;
}
```
---
## Step 11: Deploy to production
In production, translations are pre-generated at build time (no real-time API calls). Add the translate command to your build script:
```json title="package.json"
{
"scripts": {
"build": "npx gt translate && next build"
}
}
```
Set your **production** environment variables in your hosting provider (Vercel, Netlify, etc.):
```bash
GT_PROJECT_ID=your-project-id
GT_API_KEY=gtx-api-your-production-key
```
Production keys start with `gtx-api-` (not `gtx-dev-`). Get one from [dash.generaltranslation.com](https://dash.generaltranslation.com). Never prefix it with `NEXT_PUBLIC_`.
That's it — your app is now multilingual. 🎉
---
## Troubleshooting
`gt-next` stores the user's language preference in a cookie called `generaltranslation.locale`. If you previously tested with a different language, this cookie may override your selection. Clear your cookies and try again.
- [Chrome](https://support.google.com/chrome/answer/95647)
- [Firefox](https://support.mozilla.org/en-US/kb/delete-cookies-remove-info-websites-stored)
- [Safari](https://support.apple.com/en-mn/guide/safari/sfri11471/16.0/mac/11.0)
This is expected. In development, translations happen on-demand (your content is translated in real time via the API). This delay **does not exist in production** — all translations are pre-generated by `npx gt translate`.
Ambiguous text can lead to inaccurate translations. For example, "apple" could mean the fruit or the company. Add a `context` prop to help:
```jsx
Apple
```
Both ``, `useGT()`, and `getGT()` support the `context` option.
---
## Next steps
**See it in action:** Browse [working example apps](/docs/next/tutorials/examples) to see `gt-next` patterns in real projects, or jump straight to the [app catalog](https://app-catalog.generaltranslation.dev).
- [**`` Component Guide**](/docs/next/guides/t) — Learn about variables, plurals, and advanced translation patterns
- [**String Translation Guide**](/docs/next/guides/strings) — Deep dive into `useGT` and `getGT`
- [**Variable Components**](/docs/next/guides/variables) — Handle dynamic content with ``, ``, ``, and ``
- [**Pluralization**](/docs/next/api/components/plural) — Handle plural forms with the `` component
- [**Translating Page Metadata**](/docs/next/api/strings/get-gt#metadata) — Translate titles, descriptions, and OG tags with `getGT`
- [**Deploying to Production**](/docs/next/tutorials/quickdeploy) — CI/CD setup, caching, and performance optimization
- [**Shared Strings**](/docs/next/guides/shared-strings) — Translate text in arrays, config objects, and shared data with `msg()`
# gt-next: General Translation Next.js SDK: Overview
URL: https://generaltranslation.com/en-US/docs/next/introduction.mdx
---
title: Overview
description: Overview of General Translation's Next.js SDK
---
## Introduction
The General Translation Next.js SDK is an open-source internationalization (i18n) library for Next.js applications.
It provides a comprehensive set of tools to internationalize your Next.js application in an easy and maintainable way, with feature parity to other popular i18n libraries. Built on top of the [React SDK](/docs/react), it offers additional Next.js-specific features.
The SDK can be used standalone without the General Translation platform and behaves similarly to other i18n libraries.
However, it also integrates with our platform for enhanced features:
- Translation Hot Reloading in Development
- Automatic AI translations
- Syncing translations with the General Translation platform
- Native integration with our translation CDN
- On-demand translation of React components in production (on the server side)
## Concepts
There are 6 main concepts to understand about the SDK.
Initialization with [`withGTConfig`](/docs/next/api/config/with-gt-config)
The [``](/docs/next/api/components/gtprovider) component
The [``](/docs/next/api/components/t) component
The [`useGT`](/docs/next/api/strings/use-gt) hook
The [`msg`](/docs/next/api/strings/msg) function for shared strings
(Optional) The [`useTranslations`](/docs/next/api/dictionary/use-translations) hook
## Initialization with `withGTConfig`
The [`withGTConfig`](/docs/next/api/config/with-gt-config) function initializes the SDK in your Next.js application.
Add it to your `next.config.[js|ts]` file to configure the SDK:
```tsx title="next.config.ts"
import { withGTConfig } from 'gt-next/config';
const nextConfig = {
// Your next.config.ts options
};
export default withGTConfig(nextConfig, {
// Your GT configuration
});
```
See the [withGTConfig API Reference](/docs/next/api/config/with-gt-config) for more information.
## The `` component
The [``](/docs/next/api/components/gtprovider) component provides translation context to your application, including the current language and relevant translations.
```tsx
import { GTProvider } from 'gt-next';
export default function RootLayout({ children }) {
return (
{children}
);
}
```
**Important:** The provider should wrap your entire application and be placed as high in the component tree as possible, such as in your root layout.
The provider is only required for client-side features. Server-side only applications don't require it, but it can still be included.
See the [`GTProvider`](/docs/next/api/components/gtprovider) API reference for more information.
## The `` component
The [``](/docs/next/api/components/t) component is the recommended way to translate content in your application.
It is a React component that can be used to wrap any JSX element, and will automatically render the content of the element into a supported language.
We recommend using the [``](/docs/next/api/components/t) component wherever possible, since it allows for the most flexibility in translations.
Unlike strings, the [``](/docs/next/api/components/t) component can be used to translate HTML content, making it much more powerful than string translations.
### Examples
```tsx
Hello, world!
```
```tsx
Here is an image
```
```tsx
Formatting can be done easily with the `` component.
{1000}
{new Date()}
{1000}
```
The [``](/docs/next/api/components/t) component works with [variable components](/docs/next/guides/variables) like [``](/docs/next/api/components/num), [``](/docs/next/api/components/datetime), and [``](/docs/next/api/components/currency) for dynamic content formatting.
See the [`` component guide](/docs/next/guides/t) to learn about the different ways to use the [``](/docs/next/api/components/t) component.
## The `useGT` hook
The [`useGT`](/docs/next/api/strings/use-gt) hook is a React hook that can be used similarly to the [``](/docs/next/api/components/t) component, with some trade-offs.
The hook returns a function that can be used to translate strings.
```tsx
const gt = useGT();
gt('Hello, world!');
```
Compared to the [``](/docs/next/api/components/t) component, the [`useGT`](/docs/next/api/strings/use-gt) hook allows for more flexibility in your codebase.
For example, if you have a complex data structure with nested strings, a [``](/docs/next/api/components/t) component would be more difficult to use.
```tsx
const gt = useGT();
const data = {
title: gt('Hello, world!'),
description: gt('This is a description'),
};
```
See the [strings](/docs/next/guides/strings) guide to learn more about the [`useGT`](/docs/next/api/strings/use-gt) hook.
## The `msg` function
The [`msg`](/docs/next/api/strings/msg) function is used to mark strings for translation that are used across multiple components or stored in configuration objects.
This is particularly useful for shared content like navigation labels, form messages, or any text that appears in multiple places throughout your application.
```tsx
// Mark strings for translation
import { msg } from 'gt-next';
const navItems = [
{ label: msg('Home'), href: '/' },
{ label: msg('About'), href: '/about' },
{ label: msg('Contact'), href: '/contact' }
];
```
```tsx
// Decode and use the marked strings
import { useMessages } from 'gt-next';
function Navigation() {
const m = useMessages();
return (
{navItems.map(item => (
{m(item.label)}
))}
);
}
```
The [`msg`](/docs/next/api/strings/msg) function encodes strings with translation metadata, and [`useMessages`](/docs/next/api/strings/use-messages) (or [`getMessages`](/docs/next/api/strings/get-messages) for server components) decodes them.
Use [`msg`](/docs/next/api/strings/msg) for shared content that needs to be translated consistently across your application. For component-specific content, prefer [``](/docs/next/api/components/t) or [`useGT`](/docs/next/api/strings/use-gt).
See the [shared strings](/docs/next/guides/shared-strings) guide to learn more about the `msg` function.
## The `useTranslations` hook
The [`useTranslations`](/docs/next/api/dictionary/use-translations) hook is a React hook that returns a function that can be used to retrieve translations for a given key.
```tsx title="dictionary.ts"
const dictionary = {
hello: {
world: 'Hello, world!',
},
};
```
```tsx title="App.tsx"
const translate = useTranslations();
translate('hello.world');
```
This behavior is similar to other translation libraries, such as [`react-i18next`](https://react.i18next.com/) and [`next-intl`](https://next-intl-docs.vercel.app/).
We do not recommend using the [`useTranslations`](/docs/next/api/dictionary/use-translations) hook in your application. Frequent use of the [`useTranslations`](/docs/next/api/dictionary/use-translations) hook will make your codebase more difficult to maintain,
and will lead to large tech debt.
Instead, we recommend using the [``](/docs/next/api/components/t) component or the [`useGT`](/docs/next/api/strings/use-gt) hook.
If you are migrating from another i18n library, the [`useTranslations`](/docs/next/api/dictionary/use-translations) hook is a drop-in replacement and can be useful for incrementally migrating your codebase.
See the [dictionaries](/docs/next/guides/dictionaries) guide to learn more about the [`useTranslations`](/docs/next/api/dictionary/use-translations) hook.
See the [useTranslations API Reference](/docs/next/api/dictionary/use-translations) for more information.
---
## Next steps
**See it in action:** Browse [working example apps](/docs/next/tutorials/examples) showcasing each pattern, or explore the full [app catalog](https://app-catalog.generaltranslation.dev).
- Learn about how to set up your Next.js project with the SDK: [Quickstart](/docs/next)
- Learn about how to translate JSX content with the [``](/docs/next/api/components/t) component: [JSX Translation Guide](/docs/next/guides/t)
- Learn about how to translate strings with the [`useGT`](/docs/next/api/strings/use-gt) hook: [String Translation Guide](/docs/next/guides/strings)
- Learn about shared strings with the [`msg`](/docs/next/api/strings/msg) function: [Shared Strings Guide](/docs/next/guides/shared-strings)
# overview: AI Coding
URL: https://generaltranslation.com/en-US/docs/overview/ai-tools.mdx
---
title: AI Coding
description: Resources for AI coding tools including llms.txt and an MCP server
---
We provide several resources to help your AI tools work with General Translation.
## llms.txt
### llms.txt
Provide your AI coding tools with our [llms.txt](/llms.txt) file for a brief summary of our docs in an LLM-friendly format.
### llms-full.txt
Provide your AI coding tools with our [llms-full.txt](/llms-full.txt) file for the full content of our docs in an LLM-friendly format.
## MCP server
We offer a simple MCP server that AI tools like Cursor, Windsurf, and Claude Code can use to access our docs.
### Configuring the MCP server
#### Local MCP server
For AI tools which maintain a persistent connection such as **Windsurf**, **Cursor**, and **Claude Code**, you can run our MCP docs server locally.
```json title="mcp.json" copy
{
"mcpServers": {
"generaltranslation": {
"command": "npx",
"args": ["-y", "@generaltranslation/mcp@latest"]
}
}
}
```
#### Streamable-HTTP MCP
Otherwise, you can use our MCP server hosted at `https://mcp.gtx.dev`.
```json title=".mcp.json"
{
"mcpServers": {
"generaltranslation": {
"type": "streamable-http",
"url": "https://mcp.gtx.dev"
}
}
}
```
#### SSE MCP
For tools that don't support streamable-http, you can use the SSE endpoint instead.
```json title=".mcp.json"
{
"mcpServers": {
"generaltranslation": {
"type": "sse",
"url": "https://mcp.gtx.dev/sse"
}
}
}
```
### Using the MCP server
#### Cursor
To use the MCP server in Cursor, ask the AI to use the `generaltranslation` tool.
For example, you can ask the AI: "Use the generaltranslation tool to explain how to use a `` component."
#### Windsurf
To use the MCP server in Windsurf, ask the AI to use the `generaltranslation` mcp server.
For example, you can ask the AI: "Use the generaltranslation mcp server to explain how to use a `` component."
#### Claude Code
To use the MCP server in Claude Code, ask the AI to use the `generaltranslation` mcp server.
# overview: FAQs
URL: https://generaltranslation.com/en-US/docs/overview/faqs.mdx
---
title: FAQs
description: Frequently Asked Questions
---
### What is a locale?
A locale is **a language or dialect**.
For example, `en-US` is a locale code, which refers to the English language as spoken in the United States of America.
* [Read more about locales](/docs/core/locales)
* [List of supported locales](/docs/platform/supported-locales)
### Can I use the libraries without using the General Translation platform?
Yes you can!
General Translation internationalization libraries are free, open-source, and can be configured to fetch translations from any source.
Read the docs on how to load your own translations [here](/docs/next/api/config/load-translations).
### Section-specific FAQs
- [Platform](/docs/platform/faqs)
- [Locadex AI Agent](/docs/locadex/faqs)
- [Next.js App Router](/docs/next/faqs)
- [React](/docs/react/faqs)
- [React Native](/docs/react-native/faqs)
- [Core Library](/docs/core/faqs)
- [CLI](/docs/cli/faqs)
- [Sanity Plugin](/docs/sanity/faqs)
# overview: Introduction
URL: https://generaltranslation.com/en-US/docs/overview.mdx
---
title: Introduction
description: Get started with General Translation's localization and internationalization stack
---
## Quickstarts
Run `npx gt@latest`, or choose your framework below to get started:
## Launch in every language
General Translation is an entire localization and internationalization (i18n) stack,
built to ship multilingual apps from end-to-end. It includes:
- Open developer libraries for [React](/docs/react), [Next.js](/docs/next), [React Native](/docs/react-native), [Node](/docs/node/tutorials/quickstart), [Python](/docs/python), [TanStack Start](/docs/tanstack-start), and more
- An AI-first translation platform, generaltranslation.com
- [Locadex](/docs/locadex), the AI agent that internationalizes your code and translates your content continuously
## Built for developers
General Translation is trusted by incredible developer-first companies like
Cursor ,
Cognition ,
and
Clickhouse ,
in addition to world-class product companies like
Ramp ,
Profound ,
and
Partiful .
**We're proud of our users!**
# overview: Key Terms
URL: https://generaltranslation.com/en-US/docs/overview/key-terms.mdx
---
title: Key Terms
description: A guide to the key terminology used by General Translation
---
## Locale
A locale is **a language or dialect**.
In these docs, the term "locale" usually refers to the "locale code", which is a BCP 47 language tag representing a particular locale.
For example, `en-US` is a locale code, which refers to the English language as spoken in the United States of America.
* [Read more about locales](/docs/core/locales)
* [List of supported locales](/docs/platform/supported-locales)
## Translation
Who does translation? **Human translators, language model APIs**
Translation means converting content from one language or dialect, represented by a locale code, into another language or dialect, represented by another locale code.
For example:
- Translating `es` into `en-US` means "rewriting Spanish content into US English".
- Translating `es` into `en-GB` means "rewriting Spanish content into British English".
- Translating `en-US` into `en-GB` means "rewriting this US English into the British English dialect".
```javascript
// es -> en-US
gt.translate("Tenemos un ascensor", "en-US") // -> "We have an elevator"
// es -> en-GB
gt.translate("Tenemos un ascensor", "en-GB") // -> "We have a lift"
// en-GB -> en-US
gt.translate("We have a lift", "en-US") // -> "We have an elevator"
```
## Internationalization (i18n)
Who does internationalization? **Software engineers, AI coding agents**
Internationalization, also called i18n, is the process of transforming a codebase so that it can support multiple locales.
This is usually done with an internationalization library like [gt-next](/docs/next) or [gt-react](/docs/react).
Internationalization is not the process of translation itself.
Technically, you can have an *internationalized* codebase *translated* into only one language.
## Localization (l10n)
Localization, also called l10n, is the process of adapting a product for a particular locale.
This involves both internationalization **and** translation.
In some cases, localization requires more than just internationalization and translation.
For example, you might need to be able to accept payments in a different currency or follow data regulations in a different region.
# General Translation Platform: Organization
URL: https://generaltranslation.com/en-US/docs/platform/account.mdx
---
title: Organization
description: Members and organization settings
---
General Translation accounts are structured around **Organizations** and optionally **Enterprises**.
**Organizations** contain your projects and team members. Most users work within a single organization.
**Enterprises** are an optional layer above organizations for managing multiple organizations with centralized member management. If you're not part of an enterprise, those sections won't appear in your sidebar.
## Members
The Members page shows everyone with access to your organization.

### Roles
- **Owner**: Full access to all settings and member management. Can delete the organization or transfer ownership to another member.
- **Admin**: Can manage projects, members, and most settings.
- **Developer**: Technical access to projects—API keys, GitHub integration, Locadex, and usage data.
- **Editor**: Can read, edit, and review translations.
- **Member**: Can view the organization but has no specific permissions by default.
For a detailed breakdown of what each role can do, see [Roles & Permissions](/docs/platform/orgs/roles).
### Inviting members
Organization owners and admins can invite new members by email. Invitees receive a link to join the organization. The link expires after 24 hours.
For enterprise accounts, members added at the enterprise level can access all managed organizations.
## Organization settings
- **Organization name**: Update your org's display name
- **Default settings**: Configure defaults for new projects
# General Translation Platform: API Keys
URL: https://generaltranslation.com/en-US/docs/platform/api-keys.mdx
---
title: API Keys
description: Manage authentication keys with granular permissions
---
API keys authenticate applications, CI jobs, and automation with General Translation services. Create keys at the project level for one project, or at the organization level for automation that needs broader access.
Copy the full key immediately after creation. The dashboard only shows it once.
## Key scopes
| Scope | Best for |
|-------|----------|
| **Project** | A single project, deployed app, local development, previews, and project-scoped tooling |
| **Organization** | Organization-level automation, CI that works across projects, and tools that need custom permissions |
Project keys and organization keys have different creation flows. Project keys are created as production or development keys. Organization keys use a permission selector.
## Project keys
Create project keys from **Project -> API Keys**.
| Type | Prefix | Use case |
|------|--------|----------|
| **Production** | `gtx-api-` | Deployed applications and production automation |
| **Development** | `gtx-dev-` | Local development, preview environments, and test automation |
Project keys are bound to the selected project. In most project SDK and CLI workflows, use the key with your project ID:
```bash
GT_API_KEY=gtx-api-...
GT_PROJECT_ID=...
```
## Organization keys
Create organization keys from **Organization -> API Keys**.
Organization keys use the `gtx-org-` prefix and can be configured with a custom permission set. Use them for org-level automation or workflows that need to operate across projects in the organization.
## Organization key permissions
Permissions are configured per resource. `Write` includes `Read`.
| Resource | Read | Write or enabled |
|----------|------|------------------|
| **Files** | Read project files and translations | Upload source content and write translated files |
| **Context** | Read project and organization context | Manage context groups, glossary, and directives |
| **Runtime translation** | Not applicable | Translate content on demand |
| **Translation queue** | Not applicable | Queue file translation jobs for background processing |
| **Project settings** | Not applicable | Update project settings such as the default locale |
Grant each key only the permissions it needs.
## Rotate or revoke keys
Open the key list for the project or organization to review existing keys. Revoke keys that are no longer used, and create replacements when rotating credentials.
## Security practices
- Never commit keys to source control
- Store keys in environment variables or a secrets manager
- Use separate keys for development, staging, and production
- Rotate keys periodically and revoke unused ones
- Prefer the narrowest scope that works for the integration
# General Translation Platform: FAQs
URL: https://generaltranslation.com/en-US/docs/platform/faqs.mdx
---
title: FAQs
description: Frequently asked questions about the General Translation platform
---
## What is the General Translation platform?
The General Translation platform is a dashboard for managing translations, context, API keys, webhooks, and repository sync through Locadex.
## How do I get an API key?
Create a project, then open [API Keys](/docs/platform/api-keys) at the project or organization level. Project keys are used for one project. Organization keys support custom permissions for broader automation.
## Can I edit translations after they are generated?
Yes. View and edit translations from the [Translations](/docs/platform/translations) page. Use [annotations](/docs/platform/translations/annotations) to label, note, and discuss entries with your team.
## What is context?
[Context groups](/docs/platform/context) hold the glossary and directives that guide AI translation. Create groups at the organization level, assign them to projects, and set priority when groups overlap.
## How do I share terminology across projects?
Create a context group at the organization level with your shared glossary and directives, then assign it to multiple projects. Changes to the group apply everywhere it is assigned.
## How do I update existing translations after changing the glossary?
Use [Apply glossary](/docs/platform/context/apply-glossary) to update only files containing selected terms. For full file regeneration, use [Retranslate](/docs/platform/translations/retranslate).
## How do I sync dashboard edits back to GitHub?
Use [Locadex](/docs/locadex) to create pull requests for dashboard changes after editing, retranslating, or applying glossary updates.
# General Translation Platform: Overview
URL: https://generaltranslation.com/en-US/docs/platform.mdx
---
title: Overview
description: Manage translations, context, automation, and repository sync
---
The General Translation dashboard is where you manage projects, edit translations, guide AI output with context, automate translation workflows, and sync changes back to your codebase.
## Dashboard scopes
The dashboard is organized into three scopes:
| Scope | What it manages |
|-------|-----------------|
| **Enterprise** | Enterprise organizations, members, and security settings |
| **Organization** | Projects, members, shared context, org API keys, and webhooks |
| **Project** | Translations, project context, project API keys, Locadex, and settings |
Use the switcher in the header to move between scopes. Most translation work happens inside a project; shared terminology, members, and webhooks live at the organization level.
## Common workflows
**Review and edit translations**: Browse files or UI components, edit translations inline, compare versions, and search across your project. See [Editing translations](/docs/platform/translations).
**Coordinate review**: Use [annotations](/docs/platform/translations/annotations) to label entries, leave notes, and discuss translations without changing the translation itself.
**Guide AI translation**: Organize glossary terms and translation instructions into [context groups](/docs/platform/context). Shared groups can be assigned to multiple projects.
**Propagate terminology updates**: Use [Apply glossary](/docs/platform/context/apply-glossary) to update existing translations that contain selected glossary terms.
**Authenticate tools and apps**: Create [API keys](/docs/platform/api-keys) for project development, production use, and organization-level automation.
**Sync repository changes**: Use [Locadex](/docs/locadex) to push dashboard edits back to GitHub as pull requests.
**Automate event workflows**: Use [webhooks](/docs/platform/webhooks) to send translation events to your own systems.
## Navigation
The sidebar changes based on the active scope. If you do not see a page, check that you are in the right organization or project and that your role has access to the feature.
## Next steps
- [Editing translations](/docs/platform/translations)
- [Context groups](/docs/platform/context)
- [API keys](/docs/platform/api-keys)
- [Locadex Agent](/docs/locadex)
# General Translation Platform: Supported Locales
URL: https://generaltranslation.com/en-US/docs/platform/supported-locales.mdx
---
title: Supported Locales
description: A list of the locales currently supported by General Translation
---
## Search locales
Below is a list of all the [locales](/docs/core/locales) currently supported by the General Translation platform.
## Further reading
- Refer to the official [IETF Language Tag Registry](https://www.iana.org/assignments/language-subtag-registry/language-subtag-registry)
and the [BCP 47 / RFC 5646 specification](https://www.rfc-editor.org/rfc/rfc5646.html) for more information.
- See also the [W3C guide on language tags](https://www.w3.org/International/articles/language-tags/) for a practical overview.
# General Translation Platform: Webhooks
URL: https://generaltranslation.com/en-US/docs/platform/webhooks.mdx
---
title: Webhooks
description: Send translation events from an organization to your application
---
Webhooks send HTTP POST requests to your application when events occur in an organization. Use them to trigger downstream workflows after translation activity.
## Event types
Webhook endpoints can subscribe to these public events:
| Event | When it fires |
|-------|---------------|
| `translated_file.completed` | A translated file is completed and ready to download |
| `translated_file.edited` | A translated file is manually edited in the translation editor |
| `translation_job.completed` | A translation job completes |
## Add an endpoint
1. Open **Organization -> Webhooks**
2. Click **Add endpoint**
3. Enter the endpoint URL
4. Optionally add a description
5. Select the event types to deliver
6. Click **Create endpoint**
The endpoint URL must be an HTTPS endpoint that can receive POST requests.
## Manage endpoints
Open an endpoint to update its URL, description, event subscriptions, or status. You can also reveal the signing secret when you need to configure signature verification in your application.
## Review events
Open **Organization -> Webhooks -> Events** to inspect recent events and their deliveries. Use this page to confirm whether events were delivered and retry failed deliveries when available.
## Next steps
- [Editing translations](/docs/platform/translations)
- [API keys](/docs/platform/api-keys)
# python: Python Quickstart
URL: https://generaltranslation.com/en-US/docs/python.mdx
---
title: Python Quickstart
description: Add multiple languages to your Python server in under 10 minutes
---
By the end of this guide, your Python server will respond with translated content based on the request's language.
General Translation supports both **FastAPI** and **Flask**. Pick the guide that matches your framework:
---
## Overview
The Python SDK provides:
- **`t()` function** — translate any string inline, with variable interpolation
- **`derive()` function** — derive translated values from source content
- **Automatic locale detection** — parses `Accept-Language` headers out of the box
- **`gt.config.json` support** — same config file used across all GT libraries
## Quick example
First, create a `gt.config.json` in your project root:
```json title="gt.config.json"
{
"projectId": "your-project-id",
"defaultLocale": "en",
"locales": ["es", "fr"]
}
```
Then set up your app:
```python title="app.py"
from fastapi import FastAPI
from gt_fastapi import initialize_gt, t
app = FastAPI()
initialize_gt(app)
@app.get("/")
def index():
return {"message": t("Hello, world!")}
```
Then translate and publish your content:
```bash
pip install gtx-cli
gt translate --publish
```
That's it — your endpoint now returns translated content based on the request's locale.
## Next steps
- [FastAPI Quickstart](/docs/python/tutorials/fastapi-quickstart) — full setup guide for FastAPI
- [Flask Quickstart](/docs/python/tutorials/flask-quickstart) — full setup guide for Flask
- [`t()` API Reference](/docs/python/api/t) — variable interpolation and options
- [`initialize_gt()` API Reference](/docs/python/api/initialize-gt) — all configuration options
# gt-react: General Translation React SDK: FAQs
URL: https://generaltranslation.com/en-US/docs/react/faqs.mdx
---
title: FAQs
description: Frequently asked questions about gt-react
---
### What happens if there are missing translations in production?
If a translation for some content is missing in production, gt-react automatically falls back to the original source text. Your app will still render correctly — users will just see the default language for that piece of content.
### Why do I have to install the CLI tool?
The CLI tool parses the content inside all `` components and generates translations for that content in advance, so that all the translations are ready when your app is deployed to production.
In development, you don't need it because you can use development API keys to translate on demand.
### Where does the `` component get its translations?
`` can load translations from anywhere depending on how you've configured the library:
- If you have a project ID, the library can hit a free CDN
- It can store translations locally in your bundle
- It can do a mix of the two
See the [loadTranslations docs](/docs/react/api/config/load-translations) for more details.
During development, the `` component hits an API which uses a small AI model to create temporary translations so you can see them hot-reload as you write. These translations aren't stored anywhere — they're just served back to the app.
In production, `` won't do this, so your API keys are never exposed to the client.
### Does AI translation work with dynamic content and variables?
The `` component doesn't support translating dynamic content and variables directly, because the translations could potentially change with every re-render. However, you can still include dynamic content inside a `` by wrapping it with ``, ``, or `` components. This is similar to how other libraries handle string interpolation.
### Can I deploy my app without depending on GT servers?
Yes. You can do the translations yourself, then load them from your own bundle or your own CDN. See the [loadTranslations docs](/docs/react/api/config/load-translations) for details on loading translations from local files.
### Why do I get `ReferenceError: TextEncoder is not defined` in Jest?
`jest-environment-jsdom` uses an older version of jsdom that doesn't include `TextEncoder`. GT libraries use it internally for hashing. This will resolve itself once Jest updates its jsdom dependency (newer jsdom versions already support `TextEncoder`), but in the meantime you can polyfill it with a setup file:
```js title="jest.setup.js"
const { TextEncoder, TextDecoder } = require('util');
global.TextEncoder = TextEncoder;
global.TextDecoder = TextDecoder;
```
Then add it to your Jest config:
```json title="jest.config.json"
{
"setupFiles": ["./jest.setup.js"]
}
```
### How do I migrate from react-intl or i18next?
See the [migration guide](/docs/react/guides/migration) for step-by-step instructions on migrating from other i18n libraries.
# gt-react: General Translation React SDK: React Quickstart
URL: https://generaltranslation.com/en-US/docs/react.mdx
---
title: React Quickstart
description: Add multiple languages to your React app in under 10 minutes
---
By the end of this guide, your React app will display content in multiple languages, with a language switcher your users can interact with.
**Prerequisites:**
- A React app (Vite, Create React App, or similar)
- Node.js 18+
**Want automatic setup?** Run `npx gt@latest` to configure everything with the [Setup Wizard](/docs/cli/init). This guide covers manual setup.
---
## Step 1: Install the packages
`gt-react` is the library that powers translations in your app. `gt` is the CLI tool that prepares translations for production.
```bash
npm i gt-react
npm i -D gt
```
```bash
yarn add gt-react
yarn add --dev gt
```
```bash
bun add gt-react
bun add --dev gt
```
```bash
pnpm add gt-react
pnpm add --save-dev gt
```
---
## Step 2: Create a translation config file
Create a **`gt.config.json`** file in your project root. This tells the library which languages you support:
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["es", "fr", "ja"],
"files": {
"gt": {
"output": "public/_gt/[locale].json"
}
}
}
```
- **`defaultLocale`** — the language your app is written in (your source language).
- **`locales`** — the languages you want to translate into. Pick any from the [supported locales list](/docs/platform/supported-locales).
- **`files`** — tells the CLI where to save translation files. The `output` path should match the import path in your `loadTranslations` function (Step 3).
**Using Vite?** Set the output path to `"src/_gt/[locale].json"` instead of `"public/_gt/[locale].json"`. Vite imports translation files as modules, so they should live inside `src/` rather than `public/`.
---
## Step 3: Create a translation loader
`gt-react` runs entirely on the client, so it needs a function to load translation files at runtime. Create a `loadTranslations` file:
```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
try {
const translations = await import(`../public/_gt/${locale}.json`);
return translations.default;
} catch (error) {
console.warn(`No translations found for ${locale}`);
return {};
}
}
```
This function loads JSON translation files from your `public/_gt/` directory. The CLI generates these files when you run `npx gt translate`.
Since Vite translation files live in `src/_gt/` (see Step 2), update the import path:
```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
try {
const translations = await import(`./_gt/${locale}.json`);
return translations.default;
} catch (error) {
console.warn(`No translations found for ${locale}`);
return {};
}
}
```
CRA's webpack config blocks dynamic `import()` from outside `src/`. Use `fetch()` instead:
```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
try {
const response = await fetch(`${process.env.PUBLIC_URL}/_gt/${locale}.json`);
if (!response.ok) throw new Error('Not found');
return await response.json();
} catch (error) {
console.warn(`No translations found for ${locale}`);
return {};
}
}
```
---
## Step 4: Add the GTProvider to your app
The **`GTProvider`** component gives your entire app access to translations. Wrap your app at the root level:
```tsx title="src/App.tsx"
import { GTProvider } from 'gt-react';
import gtConfig from '../gt.config.json';
import loadTranslations from './loadTranslations';
export default function App() {
return (
{/* Your app content */}
);
}
```
`GTProvider` takes your config and translation loader as props. It manages locale state and makes translations available to all child components.
CRA restricts imports to files inside `src/`, so `import gtConfig from '../gt.config.json'` will fail. Either copy `gt.config.json` into `src/`, or inline the config directly:
```tsx title="src/App.tsx"
import { GTProvider } from 'gt-react';
import loadTranslations from './loadTranslations';
export default function App() {
return (
{/* Your app content */}
);
}
```
---
## Step 5: Mark content for translation
Now, wrap any text you want translated with the **``** component. `` stands for "translate":
```tsx title="src/components/Welcome.tsx"
import { T } from 'gt-react';
export default function Welcome() {
return (
Welcome to my app
This content will be translated automatically.
);
}
```
You can wrap as much or as little JSX as you want inside ``. Everything inside it — text, nested elements, even formatting — gets translated as a unit.
---
## Step 6: Add a language switcher
Drop in a **``** so users can change languages:
```tsx title="src/components/Welcome.tsx"
import { T, LocaleSelector } from 'gt-react';
export default function Welcome() {
return (
Welcome to my app
This content will be translated automatically.
);
}
```
`LocaleSelector` renders a dropdown populated with the languages from your `gt.config.json`.
---
## Step 7: Set up environment variables (optional)
To see translations in development, you need API keys from General Translation. These enable **on-demand translation** — your app translates content in real time as you develop.
Create a **`.env.local`** file with the correct prefix for your bundler:
```bash title=".env.local"
VITE_GT_API_KEY="your-dev-api-key"
VITE_GT_PROJECT_ID="your-project-id"
```
```bash title=".env.local"
REACT_APP_GT_API_KEY="your-dev-api-key"
REACT_APP_GT_PROJECT_ID="your-project-id"
```
Get your free keys at [dash.generaltranslation.com](https://dash.generaltranslation.com/signup) or by running:
```bash
npx gt auth
```
For development, use a key starting with `gtx-dev-`. Production keys (`gtx-api-`) are for CI/CD only.
Client-side bundlers like Vite and CRA require environment variables to use specific prefixes (`VITE_` or `REACT_APP_`) to be exposed to the browser. Bare `GT_API_KEY` will not be available at runtime.
Yes. Without API keys, `gt-react` works as a standard i18n library. You won't get on-demand translation in development, but you can still:
- Provide your own translation files manually
- Use all components (``, ``, `LocaleSelector`, etc.)
- Run `npx gt generate` to create translation file templates, then translate them yourself
---
## Step 8: See it working
Start your dev server:
```bash
npm run dev
```
```bash
yarn dev
```
```bash
bun dev
```
```bash
pnpm dev
```
Open your app and use the language dropdown to switch languages. You should see your content translated.
In development, translations happen on-demand — you may see a brief loading state the first time you switch to a new language. In production, translations are pre-generated and load instantly.
---
## Step 9: Translate strings (not just JSX)
For plain strings — like `placeholder` attributes, `aria-label` values, or `alt` text — use the **`useGT`** hook:
```tsx title="src/components/ContactForm.tsx"
import { useGT } from 'gt-react';
export default function ContactForm() {
const gt = useGT();
return (
);
}
```
---
## Step 10: Deploy to production
In production, translations are pre-generated at build time (no real-time API calls). Add the translate command to your build script:
```json title="package.json"
{
"scripts": {
"build": "npx gt translate && "
}
}
```
Set your **production** environment variables in your hosting provider (Vercel, Netlify, etc.):
```bash
GT_PROJECT_ID=your-project-id
GT_API_KEY=gtx-api-your-production-key
```
Production keys start with `gtx-api-` (not `gtx-dev-`). Get one from [dash.generaltranslation.com](https://dash.generaltranslation.com). Never publicly expose your `GT_API_KEY`.
That's it — your app is now multilingual. 🎉
---
## Troubleshooting
`gt-react` stores the user's language preference in a cookie called `generaltranslation.locale`. If you previously tested with a different language, this cookie may override your selection. Clear your cookies and try again.
- [Chrome](https://support.google.com/chrome/answer/95647)
- [Firefox](https://support.mozilla.org/en-US/kb/delete-cookies-remove-info-websites-stored)
- [Safari](https://support.apple.com/en-mn/guide/safari/sfri11471/16.0/mac/11.0)
This is expected. In development, translations happen on-demand (your content is translated in real time via the API). This delay **does not exist in production** — all translations are pre-generated by `npx gt translate`.
Ambiguous text can lead to inaccurate translations. For example, "apple" could mean the fruit or the company. Add a `context` prop to help:
```jsx
Apple
```
Both `` and `useGT()` support the `context` option.
---
## Next steps
- [**`` Component Guide**](/docs/react/guides/t) — Learn about variables, plurals, and advanced translation patterns
- [**String Translation Guide**](/docs/react/guides/strings) — Deep dive into `useGT`
- [**Variable Components**](/docs/react/guides/variables) — Handle dynamic content with ``, ``, ``, and ``
- [**Pluralization**](/docs/react/api/components/plural) — Handle plural forms with the `` component
- [**Deploying to Production**](/docs/react/tutorials/quickdeploy) — CI/CD setup, caching, and performance optimization
- [**Shared Strings**](/docs/react/guides/shared-strings) — Translate text in arrays, config objects, and shared data with `msg()`
# gt-react: General Translation React SDK: Overview
URL: https://generaltranslation.com/en-US/docs/react/introduction.mdx
---
title: Overview
description: Overview of General Translation's React SDK
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Introduction
The General Translation React SDK is an open-source internationalization (i18n) library for React applications.
It provides a comprehensive set of tools to internationalize your React application in an easy and maintainable way, with feature parity to other popular i18n libraries.
The SDK can be used standalone without the General Translation platform and behaves similarly to other i18n libraries.
However, it also integrates with our platform for enhanced features:
- Translation hot reloading in development
- Automatic AI translations
- Syncing translations with the General Translation platform
- Native integration with our translation CDN
## Concepts
There are 5 main concepts to understand about the SDK.
The [``](/docs/react/api/components/gtprovider) component
The [``](/docs/react/api/components/t) component
The [`useGT`](/docs/react/api/strings/use-gt) hook
The [`msg`](/docs/react/api/strings/msg) function for shared strings
(Optional) The [`useTranslations`](/docs/react/api/dictionary/use-translations) hook
## The `` component
The [``](/docs/react/api/components/gtprovider) component provides translation context to your application, including the current language and relevant translations.
```tsx
import { GTProvider } from 'gt-react';
function App() {
return (
{/* Your application content */}
);
}
```
**Important:** The provider should wrap your entire application and be placed as high in the component tree as possible, such as in your root App component.
See the [`GTProvider`](/docs/react/api/components/gtprovider) API reference for more information.
## The `` component
The [``](/docs/react/api/components/t) component is the recommended way to translate content in your application.
It is a React component that can be used to wrap any JSX element, and will automatically render the content of the element into a supported language.
We recommend using the [``](/docs/react/api/components/t) component wherever possible, since it allows for the most flexibility in translations.
Unlike strings, the [``](/docs/react/api/components/t) component can be used to translate HTML content, making it much more powerful than string translations.
### Examples
```tsx
Hello, world!
```
```tsx
Here is an image
```
```tsx
Formatting can be done easily with the `` component.
{1000}
{new Date()}
{1000}
```
The [``](/docs/react/api/components/t) component works with [variable components](/docs/react/guides/variables) like [``](/docs/react/api/components/num), [``](/docs/react/api/components/datetime), and [``](/docs/react/api/components/currency) for dynamic content formatting.
See the [`` component guide](/docs/react/guides/t) to learn about the different ways to use the [``](/docs/react/api/components/t) component.
## The `useGT` hook
The [`useGT`](/docs/react/api/strings/use-gt) hook is a React hook that can be used similarly to the [``](/docs/react/api/components/t) component, with some trade-offs.
The hook returns a function that can be used to translate strings.
```tsx
const gt = useGT();
gt('Hello, world!');
```
Compared to the [``](/docs/react/api/components/t) component, the [`useGT`](/docs/react/api/strings/use-gt) hook allows for more flexibility in your codebase.
For example, if you have a complex data structure with nested strings, a [``](/docs/react/api/components/t) component would be more difficult to use.
```tsx
const gt = useGT();
const data = {
title: gt('Hello, world!'),
description: gt('This is a description'),
};
```
See the [strings](/docs/react/guides/strings) guide to learn more about the [`useGT`](/docs/react/api/strings/use-gt) hook.
## The `msg` function
The [`msg`](/docs/react/api/strings/msg) function is used to mark strings for translation that are used across multiple components or stored in configuration objects.
This is particularly useful for shared content like navigation labels, form messages, or any text that appears in multiple places throughout your application.
```tsx
// Mark strings for translation
import { msg } from 'gt-react';
const navItems = [
{ label: msg('Home'), href: '/' },
{ label: msg('About'), href: '/about' },
{ label: msg('Contact'), href: '/contact' }
];
```
```tsx
// Decode and use the marked strings
import { useMessages } from 'gt-react';
function Navigation() {
const m = useMessages();
return (
{navItems.map(item => (
{m(item.label)}
))}
);
}
```
The [`msg`](/docs/react/api/strings/msg) function encodes strings with translation metadata, and [`useMessages`](/docs/react/api/strings/use-messages) decodes them.
Use [`msg`](/docs/react/api/strings/msg) for shared content that needs to be translated consistently across your application. For component-specific content, prefer [``](/docs/react/api/components/t) or [`useGT`](/docs/react/api/strings/use-gt).
See the [shared strings](/docs/react/guides/shared-strings) guide to learn more about the `msg` function.
## The `useTranslations` hook
The [`useTranslations`](/docs/react/api/dictionary/use-translations) hook is a React hook that returns a function that can be used to retrieve translations for a given key.
```tsx title="dictionary.ts"
const dictionary = {
hello: {
world: 'Hello, world!',
},
};
```
```tsx title="App.tsx"
const translate = useTranslations();
translate('hello.world');
```
This behavior is similar to other translation libraries, such as [`react-i18next`](https://react.i18next.com/) and [`next-intl`](https://next-intl-docs.vercel.app/).
We do not recommend using the [`useTranslations`](/docs/react/api/dictionary/use-translations) hook in your application. Frequent use of the [`useTranslations`](/docs/react/api/dictionary/use-translations) hook will make your codebase more difficult to maintain,
and will lead to large tech debt.
Instead, we recommend using the [``](/docs/react/api/components/t) component or the [`useGT`](/docs/react/api/strings/use-gt) hook.
If you are migrating from another i18n library, the [`useTranslations`](/docs/react/api/dictionary/use-translations) hook is a drop-in replacement and can be useful for incrementally migrating your codebase.
See the [dictionaries](/docs/react/guides/dictionaries) guide to learn more about the [`useTranslations`](/docs/react/api/dictionary/use-translations) hook.
See the [useTranslations API Reference](/docs/react/api/dictionary/use-translations) for more information.
---
## Next steps
- Learn about how to set up your React project with the SDK: [Quickstart](/docs/react)
- Learn about how to translate JSX content with the [``](/docs/react/api/components/t) component: [JSX Translation Guide](/docs/react/guides/t)
- Learn about how to translate strings with the [`useGT`](/docs/react/api/strings/use-gt) hook: [String Translation Guide](/docs/react/guides/strings)
- Learn about shared strings with the [`msg`](/docs/react/api/strings/msg) function: [Shared Strings Guide](/docs/react/guides/shared-strings)
# react-core-linter: React Core Linter
URL: https://generaltranslation.com/en-US/docs/react-core-linter.mdx
---
title: React Core Linter
description: ESLint plugin for GT React libraries
---
This package is v0.1.0 and not stable. Subject to breaking changes.
`@generaltranslation/react-core-linter` is an ESLint plugin that catches common implementation errors across GT's React libraries: `gt-react`, `gt-next`, and `gt-react-native`.
It checks for issues like dynamic content inside `` components and dynamic strings in translation functions, and offers autofixes.
import Video from '@/components/Video';
## Rules
- [`static-jsx`](/docs/react-core-linter/rules/static-jsx) — Ensures dynamic content in `` components is wrapped with variable components
- [`static-string`](/docs/react-core-linter/rules/static-string) — Ensures only string literals are passed to translation functions
## Getting started
See the [Quickstart guide](/docs/react-core-linter/guides/quickstart) for installation and ESLint configuration.
## Next steps
- [Release Notes](/devlog/react-core-linter_v0_1_0) - Release notes
- [The `` Component](/docs/react/guides/t) - How to use the T component
- [Variable Components](/docs/react/guides/variables) - Handle dynamic content in translations
- [String Translation](/docs/react/guides/strings) - Translate plain text strings
# react-core-linter: React Core Linter
URL: https://generaltranslation.com/en-US/docs/react-core-linter/introduction.mdx
---
title: React Core Linter
description: ESLint plugin for General Translation React Core integration
---
Provides linting rules to ensure correct usage of React Core i18n components and translation patterns.
## Rules
- [`static-jsx`](/docs/react-core-linter/rules/static-jsx) - Enforce static content in `` components
- [`static-string`](/docs/react-core-linter/rules/static-string) - Enforce static strings in translation functions
## Quickstart
Get started with the [quickstart guide](/docs/react-core-linter/guides/quickstart).
## Next steps
- [Quickstart Guide](/docs/react-core-linter/guides/quickstart) - Get started with the React Core Linter
- [The `` Component](/docs/react/guides/t) - Learn about JSX translation
- [Variable Components](/docs/react/guides/variables) - Handle dynamic content
- [String Translation](/docs/react/guides/strings) - Translate plain text strings
# react-native: FAQs
URL: https://generaltranslation.com/en-US/docs/react-native/faqs.mdx
---
title: FAQs
description: Frequently asked questions about gt-react-native
---
### What happens if there are missing translations in production?
If a translation for some content is missing in production, gt-react-native automatically falls back to the original source text. Your app will still render correctly — users will just see the default language for that piece of content.
### Why do I have to install the CLI tool?
The CLI tool parses the content inside all `` components and generates translations for that content in advance, so that all the translations are ready when your app is deployed to production.
In development, you don't need it because you can use development API keys to translate on demand.
### Where does the `` component get its translations?
`` can load translations from anywhere depending on how you've configured the library:
- If you have a project ID, the library can hit a free CDN
- It can store translations locally in your bundle
- It can do a mix of the two
See the [loadTranslations docs](/docs/react-native/api/config/load-translations) for more details.
During development, the `` component hits an API which uses a small AI model to create temporary translations so you can see them hot-reload as you write. These translations aren't stored anywhere — they're just served back to the app.
In production, `` won't do this, so your API keys are never exposed to the client.
### Does AI translation work with dynamic content and variables?
The `` component doesn't support translating dynamic content and variables directly, because the translations could potentially change with every re-render. However, you can still include dynamic content inside a `` by wrapping it with ``, ``, or `` components. This is similar to how other libraries handle string interpolation.
### Can I deploy my app without depending on GT servers?
Yes. You can do the translations yourself, then load them from your own bundle or your own CDN. See the [loadTranslations docs](/docs/react-native/api/config/load-translations) for details on loading translations from local files.
# react-native: React Native
URL: https://generaltranslation.com/en-US/docs/react-native.mdx
---
title: React Native
description: Add multiple languages to your React Native app
---
## Getting started
Add translations to your React Native app with `gt-react-native`. Choose the quickstart guide that matches your setup:
For Expo projects (SDK 49+). Uses expo-router and Expo's build system.
For bare React Native CLI projects. Uses Metro and native builds directly.
`gt-react-native` is still experimental and may not work for all projects.
Please let us know if you encounter any issues by [opening an issue on GitHub](https://github.com/generaltranslation/gt/issues).
**Want automatic setup?** Run `npx gt@latest` to configure everything with the [Setup Wizard](/docs/cli/init).
---
## What you get
- **JSX translation** with the [`` component](/docs/react-native/guides/t)
- **String translation** with the [`useGT` hook](/docs/react-native/guides/strings)
- **Variables, plurals, and branches** with [``](/docs/react-native/guides/variables), [``](/docs/react-native/api/components/plural), and [``](/docs/react-native/guides/branches)
- **On-demand translation** in development with a dev API key
- **Pre-generated translations** in production via the [`gt translate`](/docs/cli/translate) CLI command
---
## Next steps
- [**`` Component Guide**](/docs/react-native/guides/t) — Learn about variables, plurals, and advanced translation patterns
- [**String Translation Guide**](/docs/react-native/guides/strings) — Deep dive into `useGT`
- [**Variable Components**](/docs/react-native/guides/variables) — Handle dynamic content with ``, ``, ``, and ``
- [**Deploying to Production**](/docs/react-native/tutorials/quickdeploy) — CI/CD setup, caching, and performance optimization
# react-native: Overview
URL: https://generaltranslation.com/en-US/docs/react-native/introduction.mdx
---
title: Overview
description: Overview of General Translation's React Native SDK
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Introduction
The General Translation React Native SDK is an open-source internationalization (i18n) library for React Native applications.
It provides a comprehensive set of tools to internationalize your React Native application in an easy and maintainable way, with feature parity to other popular i18n libraries.
The SDK can be used standalone without the General Translation platform and behaves similarly to other i18n libraries.
However, it also integrates with our platform for enhanced features:
- Translation hot reloading in development
- Automatic AI translations
- Syncing translations with the General Translation platform
- Native integration with our translation CDN
## Concepts
There are 5 main concepts to understand about the SDK.
The [``](/docs/react-native/api/components/gtprovider) component
The [``](/docs/react-native/api/components/t) component
The [`useGT`](/docs/react-native/api/strings/use-gt) hook
The [`msg`](/docs/react-native/api/strings/msg) function for shared strings
(Optional) The [`useTranslations`](/docs/react-native/api/dictionary/use-translations) hook
## The `` component
The [``](/docs/react-native/api/components/gtprovider) component provides translation context to your application, including the current language and relevant translations.
```tsx
import { GTProvider } from 'gt-react-native';
function App() {
return (
{/* Your application content */}
);
}
```
**Important:** The provider should wrap your entire application and be placed as high in the component tree as possible, such as in your root App component.
See the [`GTProvider`](/docs/react-native/api/components/gtprovider) API reference for more information.
## The `` component
The [``](/docs/react-native/api/components/t) component is the recommended way to translate content in your application.
It is a React component that can be used to wrap any JSX element, and will automatically render the content of the element into a supported language.
We recommend using the [``](/docs/react-native/api/components/t) component wherever possible, since it allows for the most flexibility in translations.
Unlike strings, the [``](/docs/react-native/api/components/t) component can be used to translate HTML content, making it much more powerful than string translations.
### Examples
```tsx
Hello, world!
```
```tsx
Here is an image
```
```tsx
Formatting can be done easily with the `` component.
{1000}
{new Date()}
{1000}
```
The [``](/docs/react-native/api/components/t) component works with [variable components](/docs/react-native/guides/variables) like [``](/docs/react-native/api/components/num), [``](/docs/react-native/api/components/datetime), and [``](/docs/react-native/api/components/currency) for dynamic content formatting.
See the [`` component guide](/docs/react-native/guides/t) to learn about the different ways to use the [``](/docs/react-native/api/components/t) component.
## The `useGT` hook
The [`useGT`](/docs/react-native/api/strings/use-gt) hook is a React hook that can be used similarly to the [``](/docs/react-native/api/components/t) component, with some trade-offs.
The hook returns a function that can be used to translate strings.
```tsx
const gt = useGT();
gt('Hello, world!');
```
Compared to the [``](/docs/react-native/api/components/t) component, the [`useGT`](/docs/react-native/api/strings/use-gt) hook allows for more flexibility in your codebase.
For example, if you have a complex data structure with nested strings, a [``](/docs/react-native/api/components/t) component would be more difficult to use.
```tsx
const gt = useGT();
const data = {
title: gt('Hello, world!'),
description: gt('This is a description'),
};
```
See the [strings](/docs/react-native/guides/strings) guide to learn more about the [`useGT`](/docs/react-native/api/strings/use-gt) hook.
## The `msg` function
The [`msg`](/docs/react-native/api/strings/msg) function is used to mark strings for translation that are used across multiple components or stored in configuration objects.
This is particularly useful for shared content like navigation labels, form messages, or any text that appears in multiple places throughout your application.
```tsx
// Mark strings for translation
import { msg } from 'gt-react-native';
const navItems = [
{ label: msg('Home'), href: '/' },
{ label: msg('About'), href: '/about' },
{ label: msg('Contact'), href: '/contact' }
];
```
```tsx
// Decode and use the marked strings
import { useMessages } from 'gt-react-native';
function Navigation() {
const m = useMessages();
return (
{navItems.map(item => (
{m(item.label)}
))}
);
}
```
The [`msg`](/docs/react-native/api/strings/msg) function encodes strings with translation metadata, and [`useMessages`](/docs/react-native/api/strings/use-messages) decodes them.
Use [`msg`](/docs/react-native/api/strings/msg) for shared content that needs to be translated consistently across your application. For component-specific content, prefer [``](/docs/react-native/api/components/t) or [`useGT`](/docs/react-native/api/strings/use-gt).
See the [shared strings](/docs/react-native/guides/shared-strings) guide to learn more about the `msg` function.
## The `useTranslations` hook
The [`useTranslations`](/docs/react-native/api/dictionary/use-translations) hook is a React hook that returns a function that can be used to retrieve translations for a given key.
```tsx title="dictionary.ts"
const dictionary = {
hello: {
world: 'Hello, world!',
},
};
```
```tsx title="App.tsx"
const translate = useTranslations();
translate('hello.world');
```
This behavior is similar to other translation libraries, such as [`react-i18next`](https://react.i18next.com/) and [`next-intl`](https://next-intl-docs.vercel.app/).
We do not recommend using the [`useTranslations`](/docs/react-native/api/dictionary/use-translations) hook in your application. Frequent use of the [`useTranslations`](/docs/react-native/api/dictionary/use-translations) hook will make your codebase more difficult to maintain,
and will lead to large tech debt.
Instead, we recommend using the [``](/docs/react-native/api/components/t) component or the [`useGT`](/docs/react-native/api/strings/use-gt) hook.
If you are migrating from another i18n library, the [`useTranslations`](/docs/react-native/api/dictionary/use-translations) hook is a drop-in replacement and can be useful for incrementally migrating your codebase.
See the [dictionaries](/docs/react-native/guides/dictionaries) guide to learn more about the [`useTranslations`](/docs/react-native/api/dictionary/use-translations) hook.
See the [useTranslations API Reference](/docs/react-native/api/dictionary/use-translations) for more information.
---
## Next steps
- Learn about how to set up your React Native project with the SDK: [Quickstart](/docs/react-native)
- Learn about how to translate JSX content with the [``](/docs/react-native/api/components/t) component: [JSX Translation Guide](/docs/react-native/guides/t)
- Learn about how to translate strings with the [`useGT`](/docs/react-native/api/strings/use-gt) hook: [String Translation Guide](/docs/react-native/guides/strings)
- Learn about shared strings with the [`msg`](/docs/react-native/api/strings/msg) function: [Shared Strings Guide](/docs/react-native/guides/shared-strings)
# sanity: FAQs
URL: https://generaltranslation.com/en-US/docs/sanity/faqs.mdx
---
title: FAQs
description: Frequently asked questions about the GT Sanity plugin
---
### Do I need to modify my schemas?
No. The `gt-sanity` plugin works with your existing Sanity schemas as-is. You don't need to add i18n fields to your document types or restructure your data model. Translations are stored as separate documents that the plugin creates and manages for you.
### Do I need to update my GROQ queries?
Yes. The plugin creates separate translated documents with a `language` field, but it does not modify your frontend queries. You'll need to update your GROQ queries to fetch the correct language version for each user's locale. See the [quickstart](/docs/sanity/guides/quickstart#querying-translated-content) for examples.
### Which version of Sanity does the plugin support?
The `gt-sanity` plugin v2 requires Sanity Studio v5 or later (and React 19+). If you're on Sanity v3 or v4, use `gt-sanity` v1.
### Can I translate individual documents or only the entire site?
Both. You can translate individual documents one at a time, or use batch operations to translate multiple documents or your entire site at once. You can also selectively import translations by locale.
### How does the plugin handle Portable Text?
Documents are serialized to HTML for translation, preserving structure and metadata. Portable Text, nested objects, arrays, and custom schema types are all supported. You can also provide [custom serializers](/docs/sanity/guides/serialization) to control how specific field types are handled.
### Can I add the plugin to an existing project with content already in production?
Yes. The plugin is designed to work with existing Sanity projects without any migration or refactoring. It reads your existing documents and creates translated copies as separate documents. Your source content and schemas remain untouched.
### Do translations overwrite my existing content?
No. Translated content is stored in separate translated documents, not in your source documents. Your source documents are never modified. You can review, edit, and manage translations independently.
# sanity: Introduction
URL: https://generaltranslation.com/en-US/docs/sanity.mdx
---
title: Introduction
description: Overview of the General Translation Sanity CMS plugin
---
## Overview
The `gt-sanity` plugin integrates General Translation directly into Sanity Studio v5+.
It provides a complete translation workflow for your Sanity content, including auto-translation, document-level translation, and translated document management.
```typescript title="sanity.config.ts"
import { defineConfig } from 'sanity';
import { gtPlugin } from 'gt-sanity';
export default defineConfig({
// ... your existing config
plugins: [
gtPlugin({
sourceLocale: 'en',
locales: ['es', 'zh', 'ja'],
}),
],
});
```
## How it works
The plugin uses Sanity's [document-level localization](https://www.sanity.io/docs/studio/localization) approach: for each source document, it creates separate translated documents with a `language` field set to the target locale.
**Schema and query changes required.** Each document type you translate must include a `language` field in its schema (see below).
You will also need to update your frontend queries to fetch the correct language version.
See the [quickstart](/docs/sanity/guides/quickstart#querying-translated-content) for setup and GROQ query examples.
### Language field
Every document type you translate must define a `language` field:
```typescript
import { defineField, defineType } from 'sanity'
export const articleType = defineType({
name: 'article',
title: 'Article',
type: 'document',
fields: [
// ... your existing fields
defineField({
name: 'language',
type: 'string',
readOnly: true,
hidden: true,
}),
],
})
```
If you use a custom `languageField` name in your plugin config, the field name must match.
## Key features
### Document translation
Translate entire documents to multiple target locales. The plugin handles Portable Text, nested objects, arrays, and custom schema types.
### Batch operations
Translate multiple documents or your entire site all at once. Import all translations, import only missing translations, or selectively import by locale.
### Intelligent serialization
Documents are serialized to HTML for translation, preserving structure and metadata.
Translations for languages with different grammatical structures have their structures automatically modified to sound natural in the target language.
Custom serializers let you control how specific field types are handled.
## Plugin UI
The plugin provides three main UI components:
### Translate action (dialog)
The Translate action is added automatically to every document. Clicking the **Translate** button in the document action bar opens a dialog with the full translation UI — no extra configuration needed.
### Translations tab (optional)

The `TranslationsTab` can optionally be added as a dedicated document view via `structureTool`. This provides the same translation functionality as the dialog, embedded as a tab in the document editor.
See the [quickstart](/docs/sanity/guides/quickstart#configuration) for setup instructions.
### Translations page

The Translations page is a Sanity page that provides a site-wide view of the translations for your entire site.
From this central management page, you can:
- Bulk generate translations for all documents
- Bulk import translations for all documents
- Bulk import translations for specific documents
- Repair language references and links to other documents
- Bulk publish translations for every document
## Supported content types
The plugin handles most Sanity schema types.
Custom types can be configured with [custom serializers](/docs/sanity/guides/serialization).
Fields like slugs can be configured with `dedupeFields` so new translated documents start with a source-derived value and a unique locale suffix, such as `about-es` or `about-fr`.
## Next steps
- [Quickstart](/docs/sanity/guides/quickstart) - Get started with installation and setup
- [Configuration Guide](/docs/sanity/guides/configuration) - Customize plugin behavior
- [Serialization Guide](/docs/sanity/guides/serialization) - Custom serialization rules
# tanstack-start: TanStack Start Quickstart
URL: https://generaltranslation.com/en-US/docs/tanstack-start.mdx
---
title: TanStack Start Quickstart
description: Internationalize your TanStack Start app with gt-tanstack-start
---
**Prerequisites:** TanStack Start project with React 16.8+
**Experimental:** `gt-tanstack-start` is under active development and not yet recommended for production use.
## Installation
Install `gt-tanstack-start`, `gt-react`, and the `gt` CLI:
```bash
npm i gt-tanstack-start gt-react
npm i -D gt
```
```bash
yarn add gt-tanstack-start gt-react
yarn add --dev gt
```
```bash
bun add gt-tanstack-start gt-react
bun add --dev gt
```
```bash
pnpm add gt-tanstack-start gt-react
pnpm add --save-dev gt
```
`gt-react` is required as a direct dependency so the `gt` CLI can detect `` components in your source code.
## Configuration
### `gt.config.json`
Create a `gt.config.json` in your project root:
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["es", "ja"],
"files": {
"gt": {
"output": "src/_gt/[locale].json"
}
}
}
```
Translation files **must** be inside `src/` for Vite's dynamic imports to work. Using `public/` will not work.
### Translation loader
Create a `loadTranslations.ts` file in your project root:
```ts title="loadTranslations.ts"
export default async function loadTranslations(locale: string) {
const translations = await import(`./src/_gt/${locale}.json`);
return translations.default;
}
```
### Root route setup
Update `src/routes/__root.tsx` to initialize GT and provide translations:
```tsx title="src/routes/__root.tsx"
import {
HeadContent,
Scripts,
createRootRoute,
} from '@tanstack/react-router'
import {
initializeGT,
GTProvider,
getTranslations,
getLocale,
LocaleSelector,
} from 'gt-tanstack-start'
import gtConfig from '../../gt.config.json'
import loadTranslations from '../../loadTranslations'
// Initialize GT at the module level
initializeGT({
...gtConfig,
loadTranslations,
})
export const Route = createRootRoute({
head: () => ({
meta: [
{ charSet: 'utf-8' },
{ name: 'viewport', content: 'width=device-width, initial-scale=1' },
],
}),
loader: async () => {
return {
translations: await getTranslations(),
locale: getLocale(),
}
},
shellComponent: RootDocument,
})
function RootDocument({ children }: { children: React.ReactNode }) {
const { translations, locale } = Route.useLoaderData()
return (
{children}
)
}
```
## Usage
Wrap content in `` to translate it. Import `` from `gt-react`:
```tsx title="src/routes/index.tsx"
import { createFileRoute } from '@tanstack/react-router'
import { T } from 'gt-react'
export const Route = createFileRoute('/')({ component: Home })
function Home() {
return (
Welcome to our app!
This content is automatically translated.
)
}
```
Import `` from `gt-react` (not `gt-tanstack-start`). The `gt` CLI scans for `gt-react` imports to find translatable content.
## Generate translations
### Using General Translation (recommended)
Run the `gt translate` command to generate translations:
```bash
npx gt translate
```
This sends your content to the General Translation API and downloads translated JSON files to `src/_gt/`.
You'll need environment variables for the API:
```bash title=".env"
GT_API_KEY="your-api-key"
GT_PROJECT_ID="your-project-id"
```
Get your free API keys at [dash.generaltranslation.com](https://dash.generaltranslation.com/signup) or run:
```bash
npx gt auth
```
### Manual translations
If you prefer to manage translations yourself:
1. Generate source language files:
```bash
npx gt generate
```
2. Translate the generated JSON files manually
3. Place them at `src/_gt/{locale}.json`
## Testing
Start the dev server:
```bash
npm run dev
```
```bash
yarn dev
```
```bash
bun run dev
```
```bash
pnpm dev
```
Visit [localhost:3000](http://localhost:3000) and use the locale selector to switch languages. Translations are loaded from local JSON files, so language switching is instant.
## Deployment
Add the translation step to your build script:
```json title="package.json"
{
"scripts": {
"build": "npx gt translate && vite build"
}
}
```
## Example app
See the complete working example: [tanstack-start-basic](https://github.com/generaltranslation/gt/tree/main/examples/tanstack-start-basic)
---
## Next steps
- Read the [overview](/docs/tanstack-start/introduction) for a deeper look at the API
- Learn about [variable components](/docs/react/guides/variables) like ``, ``, and ``
- Explore the [`` component](/docs/react/api/components/t) API reference
# tanstack-start: Overview
URL: https://generaltranslation.com/en-US/docs/tanstack-start/introduction.mdx
---
title: Overview
description: Overview of General Translation's TanStack Start SDK
---
## Introduction
`gt-tanstack-start` is an open-source internationalization (i18n) integration for [TanStack Start](https://tanstack.com/start) applications.
It brings the same developer experience as [`gt-next`](/docs/next) — wrap content in ``, and it gets translated — to the TanStack Start framework. Built on top of [`gt-react`](/docs/react), it adds TanStack Start–specific features like isomorphic locale detection and root loader integration.
**Experimental:** `gt-tanstack-start` is under active development. APIs may change between minor versions. It is not yet recommended for production use.
## How it works
Initialize with [`initializeGT()`](#initialization-with-initializegt) in your root route
Load translations in the [root loader](#root-loader)
Wrap your app with [``](#the-gtprovider-component)
Use [``](#the-t-component) to translate content
## Initialization with `initializeGT`
The `initializeGT()` function configures the i18n manager. Call it at the top of your root route file:
```tsx title="src/routes/__root.tsx"
import { initializeGT } from 'gt-tanstack-start'
import gtConfig from '../../gt.config.json'
import loadTranslations from '../../loadTranslations'
initializeGT({
...gtConfig,
loadTranslations,
})
```
## Root loader
Use `getTranslations()` and `getLocale()` in your root route's loader to fetch the right translations for the current request:
```tsx title="src/routes/__root.tsx"
import { getTranslations, getLocale } from 'gt-tanstack-start'
export const Route = createRootRoute({
loader: async () => {
return {
translations: await getTranslations(),
locale: getLocale(),
}
},
// ...
})
```
## The `` component
The `` provides translation context to all child components. Pass the translations and locale from the loader:
```tsx title="src/routes/__root.tsx"
import { GTProvider } from 'gt-tanstack-start'
function RootDocument({ children }: { children: React.ReactNode }) {
const { translations, locale } = Route.useLoaderData()
return (
{children}
)
}
```
## The `` component
The [``](/docs/react/api/components/t) component translates JSX content. Wrap any elements and they render in the user's language:
```tsx
import { T } from 'gt-react'
function Welcome() {
return (
Welcome to our app!
This content is automatically translated.
)
}
```
Import `` from `gt-react`, not from `gt-tanstack-start`. This ensures the `gt` CLI can detect your translatable content when generating translation files.
## Locale selector
Add a `` to let users switch languages:
```tsx
import { LocaleSelector } from 'gt-tanstack-start'
function Nav() {
return (
)
}
```
---
## Next steps
- Set up your project with the [quickstart guide](/docs/tanstack-start)
- Browse the [example app](https://github.com/generaltranslation/gt/tree/main/examples/tanstack-start-basic)
- Learn about [variable components](/docs/react/guides/variables) like ``, ``, and ``
# generaltranslation: General Translation Core SDK: GT Constructor
URL: https://generaltranslation.com/en-US/docs/core/class/constructor.mdx
---
title: GT Constructor
description: API reference for the GT class constructor
---
## Overview
The `GT` constructor creates a new instance of the General Translation class, which provides access to all translation, formatting, and locale functionality.
```typescript
import { GT } from 'generaltranslation';
const gt = new GT({
apiKey: 'your-api-key',
projectId: 'your-project-id',
sourceLocale: 'en',
targetLocale: 'es'
});
```
The constructor will automatically check the environment for `GT_API_KEY`, `GT_DEV_API_KEY`, and `GT_PROJECT_ID` environment variables, so you can omit them from the constructor parameters.
Additionally, it will validate all provided locale codes.
---
## Reference
### Parameters
The `GTConstructorParams` object supports the following properties:
| Property | Type | Optional | Description |
|----------|------|----------|-------------|
| `apiKey` | `string` | ✓ | Production API key for translation service |
| `devApiKey` | `string` | ✓ | Development API key (takes precedence in development) |
| `projectId` | `string` | ✓ | Unique project identifier |
| `sourceLocale` | `string` | ✓ | Default source locale for translations |
| `targetLocale` | `string` | ✓ | Default target locale for translations |
| `locales` | `string[]` | ✓ | Array of supported locale codes |
| `baseUrl` | `string` | ✓ | Custom API base URL (for enterprise deployments) |
| `customMapping` | `CustomMapping` | ✓ | Custom locale code mappings and definitions |
### Returns
A new `GT` class instance with all translation and locale methods available.
---
## Examples
### Basic usage
```typescript
import { GT } from 'generaltranslation';
// Minimal setup - uses environment variables
const gt = new GT();
```
### With API credentials
```typescript
const gt = new GT({
projectId: 'my-project-id',
apiKey: 'my-api-key',
targetLocale: 'fr'
});
```
### With custom locale mapping
A custom mapping can be provided.
This lets the user (1) use aliases for locale codes which, (2) can override the standard BCP 47 validation, and (3) override the standard BCP 47 locale information.
For example, say you wanted to use `cn` as an alias for `zh`.
Because the General Translation API does not support `cn`, you must specify a custom mapping.
```typescript
const gt = new GT({
projectId: 'my-project-id',
apiKey: 'my-api-key',
targetLocale: 'es',
customMapping: {
'cn': { code: 'zh' }
}
});
```
You can do other things with custom mappings, such as add custom names, emojis, etc.
```typescript
const gt = new GT({
projectId: 'my-project-id',
apiKey: 'my-api-key',
targetLocale: 'es',
customMapping: { 'en-US': { name: 'Mandarin', emoji: '🇫🇷' } }
});
```
---
## Notes
- All parameters are optional, but API operations will require `apiKey` and `projectId`
- The constructor validates all locale codes immediately, throwing errors for invalid codes
- Custom mappings take precedence over standard BCP 47 validation
## Next steps
- Configure your instance with [`setConfig`](/docs/core/class/set-config)
- Start translating with [`translate`](/docs/core/class/methods/translation/translate)
- Learn about [`GTConstructorParams` type](/docs/core/types/gt-constructor-params)
# generaltranslation: General Translation Core SDK: setConfig
URL: https://generaltranslation.com/en-US/docs/core/class/set-config.mdx
---
title: setConfig
description: API reference for the GT setConfig method
---
## Overview
The `setConfig` method updates the configuration of an existing GT instance.
This allows you to modify API credentials, locales, and other settings after the instance has been created.
```typescript
const gt = new GT();
gt.setConfig({
apiKey: 'your-new-api-key',
projectId: 'your-project-id',
sourceLocale: 'en',
targetLocale: 'es'
});
```
The `setConfig` method will validate all provided locale codes and merge with any existing configuration that was passed to the constructor.
---
## Reference
### Parameters
The `GTConstructorParams` object supports the same properties as the constructor:
| Property | Type | Optional | Description |
|----------|------|----------|-------------|
| `apiKey` | `string` | ✓ | Production API key for translation service |
| `devApiKey` | `string` | ✓ | Development API key |
| `projectId` | `string` | ✓ | Unique project identifier |
| `sourceLocale` | `string` | ✓ | Default source locale for translations |
| `targetLocale` | `string` | ✓ | Default target locale for translations |
| `locales` | `string[]` | ✓ | Array of supported locale codes |
| `baseUrl` | `string` | ✓ | Custom API base URL |
| `customMapping` | `CustomMapping` | ✓ | Custom locale code mappings |
### Returns
`void` - The method updates the instance configuration in-place.
---
## Example
In this example, we switch the target locale from Spanish to French.
```typescript
const gt = new GT({
sourceLocale: 'en',
targetLocale: 'es'
});
// Switch to French
gt.setConfig({
targetLocale: 'fr'
});
```
---
## Notes
- Configuration changes take effect immediately for subsequent method calls
- Environment variables are not re-read when calling `setConfig`
- Custom mappings completely replace existing mappings (not merged)
- The update is **not atomic** — if validation fails partway through (e.g., on the second locale), earlier properties may already be set
- The method is synchronous and returns `void`
## Next steps
- **[Initialize with constructor](/docs/core/class/constructor)**
- **[Start translating content](/docs/core/class/methods/translation/translate)**
- **[Learn about GTConstructorParams](/docs/core/types/gt-constructor-params)**
# generaltranslation: General Translation Core SDK: Content
URL: https://generaltranslation.com/en-US/docs/core/types/Content.mdx
---
title: Content
description: Union type representing all supported content formats for translation
---
## Overview
`Content` represents all supported content formats for translation.
```typescript
type Content = JsxChildren | IcuMessage | I18nextMessage;
```
## Type definition
### Union members
| Type | Description | Use Case |
|------|-------------|----------|
| `JsxChildren` | Rich JSX content with elements and variables | React components, structured HTML content |
| `IcuMessage` | ICU MessageFormat strings | Complex pluralization, date/number formatting |
| `I18nextMessage` | i18next compatible message strings | Simple interpolation, existing i18next projects |
---
## Examples
### JSX content
```typescript copy
const jsxContent: Content = {
t: 'div',
c: ['Hello ', { k: 'userName' }]
};
```
### ICU message format
```typescript copy
const icuContent: Content = 'Hello {name}!' as IcuMessage;
```
### i18next format
```typescript copy
const i18nextContent: Content = 'Welcome back, {{name}}!' as I18nextMessage;
```
---
## Notes
* `Content` unifies different message formats under a single type
* Content type can be inferred from structure or explicitly specified
## Related types
* [`JsxChildren`](/docs/core/types/jsx-children) - JSX content structure
* [`DataFormat`](/docs/core/types/data-format) - Format specification
# generaltranslation: General Translation Core SDK: TranslateManyEntry
URL: https://generaltranslation.com/en-US/docs/core/types/Entry.mdx
---
title: TranslateManyEntry
description: Type definition for translation entries used in translate and translateMany operations
---
## Overview
`TranslateManyEntry` represents the input type for [`translate`](/docs/core/class/methods/translation/translate) and [`translateMany`](/docs/core/class/methods/translation/translate-many). It can be a plain string or an object with source content and optional metadata.
```typescript
type TranslateManyEntry = string | { source: Content; metadata?: EntryMetadata };
```
## Variants
### String
A plain string is the simplest form — it will be translated as-is:
```typescript
'Hello, world!'
```
### Object
An object with `source` and optional `metadata`:
| Property | Type | Description |
|----------|------|-------------|
| `source` | `Content` | Source content to translate |
| `metadata?` | `EntryMetadata` | Optional metadata for translation customization |
### Content type
```typescript
type Content = JsxChildren | IcuMessage | StringMessage | I18nextMessage;
```
---
## Examples
### Plain strings
```typescript copy
import { GT } from 'generaltranslation';
const gt = new GT({ apiKey: 'your-api-key', projectId: 'your-project-id' });
// Single string
const result = await gt.translate('Hello, world!', 'es');
// Array of strings
const results = await gt.translateMany(['Home', 'About', 'Contact'], 'es');
```
### Objects with metadata
```typescript copy
import { GT, TranslateManyEntry } from 'generaltranslation';
const gt = new GT({ apiKey: 'your-api-key', projectId: 'your-project-id' });
const entries: TranslateManyEntry[] = [
{ source: 'Hello, world!' },
{
source: '{count, plural, other {{count} items}}',
metadata: {
dataFormat: 'ICU',
context: 'Item count display'
}
}
];
const results = await gt.translateMany(entries, { targetLocale: 'es' });
```
## Related types
* [`EntryMetadata`](/docs/core/types/entry-metadata) - Metadata options
* [`TranslateManyResult`](/docs/core/types/translate-many-result) - Batch translation results
* [`Content`](/docs/core/types/Content) - Content type union
# generaltranslation: General Translation Core SDK: Variable
URL: https://generaltranslation.com/en-US/docs/core/types/Variable.mdx
---
title: Variable
description: Type definition for variables used in translation content
---
## Overview
`Variable` represents a placeholder for dynamic content in translations.
```typescript
type Variable = {
k: string;
i?: number;
v?: VariableType;
};
```
## Properties
| Property | Type | Description |
|----------|------|-------------|
| `k` | `string` | Variable key/name |
| `i?` | `number` | Internal identifier |
| `v?` | `VariableType` | Formatting type |
### VariableType
```typescript
type VariableType = 'v' | 'n' | 'd' | 'c';
```
| Value | Description |
|-------|-------------|
| `'v'` | Plain text substitution |
| `'n'` | Number formatting |
| `'d'` | Date formatting |
| `'c'` | Currency formatting |
## Examples
### Basic usage
```typescript copy
import { Variable } from 'generaltranslation';
// Text variable
const nameVariable: Variable = {
k: 'userName'
};
// Number variable
const countVariable: Variable = {
k: 'itemCount',
v: 'n'
};
// Currency variable
const priceVariable: Variable = {
k: 'price',
v: 'c'
};
```
### In JSX content
```typescript copy
const welcomeContent = [
'Welcome back, ',
{ k: 'userName' } as Variable,
'! You have ',
{ k: 'messageCount', v: 'n' } as Variable,
' messages.'
];
```
## Related types
* [`VariableType`](/docs/core/types/variable-type) - Formatting type specifications
# generaltranslation: General Translation Core SDK: CustomMapping
URL: https://generaltranslation.com/en-US/docs/core/types/custom-mapping.mdx
---
title: CustomMapping
description: Type definition for custom locale code mappings and enhanced locale metadata
---
## Overview
`CustomMapping` defines custom locale code mappings and metadata that extends or overrides standard BCP-47 locale information.
```typescript
type CustomMapping = Record>;
```
## Type definition
### Structure
`CustomMapping` is a record where:
- **Keys**: Custom locale codes or aliases (e.g., `'simplified-chinese'`, `'company-english'`)
- **Values**: Either a simple string name or partial `LocaleProperties` object
### Value types
| Type | Description | Example |
|------|-------------|---------|
| `string` | Simple display name | `'Simplified Chinese'` |
| `Partial` | Enhanced locale metadata | `{ code: 'zh-CN', name: 'Chinese', emoji: '🇨🇳' }` |
---
## Examples
### Simple string mappings
```typescript copy
const simpleMapping: CustomMapping = {
'english': 'English',
'spanish': 'Spanish',
'mexican-spanish': 'Mexican Spanish'
};
const gt = new GT({
sourceLocale: 'english',
targetLocale: 'spanish',
customMapping: simpleMapping
});
```
### Enhanced locale metadata
```typescript copy
const enhancedMapping: CustomMapping = {
'simplified-chinese': {
code: 'zh-CN',
name: 'Simplified Chinese',
nativeName: '简体中文',
regionName: 'China',
emoji: '🇨🇳'
}
};
```
---
## Notes
* Custom mappings override standard BCP-47 locale resolution
* String values provide simple display names
* Partial LocaleProperties allow detailed locale customization
* Custom mappings are resolved during GT instance initialization
## Related types
* [`LocaleProperties`](/docs/core/types/locale-properties) - Complete locale metadata structure
# generaltranslation: General Translation Core SDK: DataFormat
URL: https://generaltranslation.com/en-US/docs/core/types/data-format.mdx
---
title: DataFormat
description: Enumeration of supported content format types for translation
---
## Overview
`DataFormat` specifies the format of translatable content.
```typescript
type DataFormat = 'JSX' | 'ICU' | 'I18NEXT' | 'STRING';
```
## Type definition
### Values
| Value | Description | Content Type | Use Case |
|-------|-------------|--------------|----------|
| `'JSX'` | JSX/React component format | `JsxChildren` | Rich UI components with elements and variables |
| `'ICU'` | ICU MessageFormat | `IcuMessage` (string) | Complex formatting with plurals, dates, numbers |
| `'I18NEXT'` | i18next message format | `I18nextMessage` (string) | Simple interpolation, existing i18next projects |
| `'STRING'` | Plain string format | `string` | Simple text content |
### Format characteristics
| Format | Variables | Pluralization | HTML Elements | Date/Number Formatting |
|--------|-----------|---------------|---------------|----------------------|
| **JSX** | ✅ Rich variables | ✅ Via branching | ✅ Full HTML support | ✅ Via variables |
| **ICU** | ✅ `{variable}` syntax | ✅ Built-in plurals | ❌ Text only | ✅ Built-in formatters |
| **I18NEXT** | ✅ `{{variable}}` syntax | ✅ Via count | ❌ Text only | ✅ Via formatters |
| **STRING** | ❌ | ❌ | ❌ | ❌ |
---
## Examples
### Format specification
```typescript copy
const icuEntry: TranslateManyEntry = {
source: 'Hello {name}',
metadata: { dataFormat: 'ICU' }
};
const plainEntry: TranslateManyEntry = {
source: 'Hello, world!',
metadata: { dataFormat: 'STRING' }
};
```
---
## Notes
* DataFormat determines how content is processed by the translation system
* Format specification in metadata ensures proper content processing
* Auto-detection is possible but explicit specification is recommended
## Related types
* [`Content`](/docs/core/types/Content) - Union of all content format types
* [`JsxChildren`](/docs/core/types/jsx-children) - JSX format content
# generaltranslation: General Translation Core SDK: EnqueueFilesOptions
URL: https://generaltranslation.com/en-US/docs/core/types/enqueue-files-options.mdx
---
title: EnqueueFilesOptions
description: Configuration options for batch file translation operations
---
## Overview
This is the **internal** type used by the library. The user-facing type passed to [`enqueueFiles`](/docs/core/class/methods/translation/enqueue-files) is `EnqueueOptions`, which is a subset of this type.
`EnqueueFilesOptions` is the full internal configuration type for batch file translation operations.
```typescript
type EnqueueFilesOptions = {
requireApproval?: boolean;
description?: string;
sourceLocale?: string;
targetLocales: string[];
version?: string;
_versionId?: string;
timeout?: number;
modelProvider?: string;
force?: boolean;
};
```
## Properties
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `requireApproval?` | `boolean` | No | Require approval workflow |
| `description?` | `string` | No | Job description |
| `sourceLocale?` | `string` | No | Source locale override |
| `targetLocales` | `string[]` | **Yes** | Target locale codes |
| `version?` | `string` | No | Version identifier |
| `_versionId?` | `string` | No | Internal version ID (used by the library) |
| `timeout?` | `number` | No | Request timeout (ms) |
| `modelProvider?` | `string` | No | Translation model provider |
| `force?` | `boolean` | No | Force reprocessing |
## Examples
### Basic usage
```typescript copy
import { GT, EnqueueFilesOptions } from 'generaltranslation';
const options: EnqueueFilesOptions = {
targetLocales: ['es', 'fr', 'de'],
requireApproval: true
};
const result = await gt.enqueueFiles(files, options);
```
### Development vs production
```typescript copy
// Development
const devOptions: EnqueueFilesOptions = {
targetLocales: ['es'],
requireApproval: false
};
// Production
const prodOptions: EnqueueFilesOptions = {
targetLocales: ['es', 'fr', 'de', 'ja'],
requireApproval: true,
modelProvider: 'premium'
};
```
## Related types
* [`FileToTranslate`](/docs/core/types/file-to-translate) - File input structure
# generaltranslation: General Translation Core SDK: EntryMetadata
URL: https://generaltranslation.com/en-US/docs/core/types/entry-metadata.mdx
---
title: EntryMetadata
description: Type definition for metadata that customizes translation behavior
---
## Overview
`EntryMetadata` provides optional configuration for [`TranslateManyEntry`](/docs/core/types/Entry) objects in translation operations.
```typescript
type EntryMetadata = {
id?: string;
hash?: string;
context?: string;
maxChars?: number;
dataFormat?: DataFormat;
actionType?: ActionType;
};
```
## Properties
| Property | Type | Description |
|----------|------|-------------|
| `id?` | `string` | Unique identifier for the entry |
| `hash?` | `string` | Content hash for caching and deduplication |
| `context?` | `string` | Context hint for translators (e.g., "Button text", "Navigation menu") |
| `maxChars?` | `number` | Maximum character limit for the translation |
| `dataFormat?` | [`DataFormat`](/docs/core/types/data-format) | Content format specification (`'JSX'`, `'ICU'`, `'I18NEXT'`, or `'STRING'`) |
| `actionType?` | `ActionType` | Translation model preference |
### Related types
```typescript
type DataFormat = 'JSX' | 'ICU' | 'I18NEXT' | 'STRING';
type ActionType = 'fast';
```
## Examples
### Basic usage
```typescript copy
import { GT, TranslateManyEntry } from 'generaltranslation';
const entry: TranslateManyEntry = {
source: 'Save',
metadata: {
context: 'Button text',
actionType: 'fast'
}
};
const gt = new GT({ apiKey: 'your-api-key', projectId: 'your-project-id' });
const result = await gt.translate(entry, 'es');
```
### With ICU format
```typescript copy
const entry: TranslateManyEntry = {
source: '{count, plural, other {{count} items}}',
metadata: {
dataFormat: 'ICU',
context: 'Item count'
}
};
```
## Related types
* [`TranslateManyEntry`](/docs/core/types/Entry) - Parent type using this metadata
* [`DataFormat`](/docs/core/types/data-format) - Content format options
# generaltranslation: General Translation Core SDK: FileToTranslate
URL: https://generaltranslation.com/en-US/docs/core/types/file-to-translate.mdx
---
title: FileToTranslate
description: Type definition for file objects used in batch file translation operations
---
## Overview
This type is deprecated. The current API uses `FileToUpload` for uploading files (via [`uploadSourceFiles`](/docs/core/class/methods/translation/upload-source-files)) and `FileReferenceIds` for enqueueing translations (via [`enqueueFiles`](/docs/core/class/methods/translation/enqueue-files)).
`FileToTranslate` was previously used to represent a file object for batch translation operations.
```typescript
type FileToTranslate = {
content: string;
fileName: string;
fileFormat: FileFormat;
formatMetadata?: Record;
dataFormat?: DataFormat;
};
```
## Properties
| Property | Type | Required | Description |
|----------|------|----------|-------------|
| `content` | `string` | **Yes** | Raw file content |
| `fileName` | `string` | **Yes** | File identifier |
| `fileFormat` | `FileFormat` | **Yes** | File format |
| `formatMetadata?` | `Record` | No | Format-specific metadata |
| `dataFormat?` | `DataFormat` | No | Data format within file |
### Related types
```typescript
type FileFormat = 'JSON' | 'PO' | 'POT' | 'MDX' | 'MD' | 'HTML' | 'TXT' | string;
type DataFormat = 'JSX' | 'ICU' | 'I18NEXT';
```
## Examples
### JSON file
```typescript copy
import { FileToTranslate } from 'generaltranslation';
const jsonFile: FileToTranslate = {
content: JSON.stringify({
"welcome": "Welcome",
"save": "Save"
}),
fileName: 'common.json',
fileFormat: 'JSON',
dataFormat: 'I18NEXT'
};
```
### MDX file
```typescript copy
const mdxFile: FileToTranslate = {
content: `# Getting Started\n\nWelcome to our platform!`,
fileName: 'docs/start.mdx',
fileFormat: 'MDX',
dataFormat: 'JSX'
};
```
## Related types
* [`EnqueueFilesOptions`](/docs/core/types/enqueue-files-options) - Batch processing options
# generaltranslation: General Translation Core SDK: GTConstructorParams
URL: https://generaltranslation.com/en-US/docs/core/types/gt-constructor-params.mdx
---
title: GTConstructorParams
description: TypeScript interface for GT class constructor parameters
---
## Overview
`GTConstructorParams` defines configuration options for GT class initialization.
```typescript
interface GTConstructorParams {
apiKey?: string;
devApiKey?: string;
sourceLocale?: string;
targetLocale?: string;
locales?: string[];
projectId?: string;
baseUrl?: string;
customMapping?: CustomMapping;
}
```
All properties are optional. The constructor reads `GT_API_KEY`, `GT_DEV_API_KEY`, and `GT_PROJECT_ID` from environment variables if not provided.
## Properties
| Property | Type | Description |
|----------|------|-------------|
| `apiKey?` | `string` | Production API key |
| `devApiKey?` | `string` | Development API key |
| `sourceLocale?` | `string` | Default source locale |
| `targetLocale?` | `string` | Default target locale |
| `locales?` | `string[]` | Supported locale codes |
| `projectId?` | `string` | Project identifier |
| `baseUrl?` | `string` | Custom API endpoint |
| `customMapping?` | `CustomMapping` | Custom locale mappings |
## Examples
### Basic setup
```typescript copy
const gt = new GT({
apiKey: 'your-api-key',
sourceLocale: 'en',
targetLocale: 'es',
locales: ['en', 'es', 'fr']
});
```
### With environment variables
```typescript copy
const gt = new GT({
sourceLocale: 'en',
targetLocale: 'es'
});
// Uses GT_API_KEY and GT_PROJECT_ID from environment
```
## Related types
* [`CustomMapping`](/docs/core/types/custom-mapping) - Custom locale definitions
# generaltranslation: General Translation Core SDK: JsxChild
URL: https://generaltranslation.com/en-US/docs/core/types/jsx-child.mdx
---
title: JsxChild
description: Union type representing individual elements within JSX content
---
## Overview
`JsxChild` represents a single element within JSX content.
```typescript
type JsxChild = string | JsxElement | Variable;
```
## Union members
| Type | Description |
|------|-------------|
| `string` | Plain text content |
| `JsxElement` | Structured element |
| `Variable` | Dynamic placeholder |
## Examples
### Basic types
```typescript copy
import { JsxChild, Variable } from 'generaltranslation';
// String
const text: JsxChild = "Welcome!";
// Variable
const name: JsxChild = { k: 'userName' } as Variable;
// Element
const link: JsxChild = {
t: 'a',
c: ['Click here']
};
```
## Related types
* [`JsxChildren`](/docs/core/types/jsx-children) - Collections of JsxChild elements
* [`JsxElement`](/docs/core/types/jsx-element) - Structured elements
# generaltranslation: General Translation Core SDK: JsxChildren
URL: https://generaltranslation.com/en-US/docs/core/types/jsx-children.mdx
---
title: JsxChildren
description: Type definition for JSX content that can be translated and rendered
---
## Overview
`JsxChildren` represents JSX content containing text, elements, and variables for translation.
```typescript
type JsxChildren = JsxChild | JsxChild[];
```
## Structure
```typescript
type JsxChild = string | JsxElement | Variable;
```
| Type | Description |
|------|-------------|
| `string` | Plain text content |
| `JsxElement` | Structured element |
| `Variable` | Dynamic placeholder |
### JsxElement
```typescript
type JsxElement = {
t?: string; // tag name
i?: number; // id
d?: GTProp; // GT properties
c?: JsxChildren; // children
};
```
## Examples
### Basic usage
```typescript copy
import { JsxChildren, Variable } from 'generaltranslation';
// Simple text
const text: JsxChildren = "Welcome!";
// Text with variables
const greeting: JsxChildren = [
"Hello, ",
{ k: 'userName' } as Variable,
"!"
];
```
### Structured elements
```typescript copy
// Div element
const divElement: JsxChildren = {
t: 'div',
c: ['Content here']
};
// Link with title
const linkElement: JsxChildren = {
t: 'a',
d: { ti: 'Visit homepage' },
c: ['Click here']
};
```
## Related types
* [`JsxChild`](/docs/core/types/jsx-child) - Individual child element types
* [`JsxElement`](/docs/core/types/jsx-element) - Structured element definitions
# generaltranslation: General Translation Core SDK: JsxElement
URL: https://generaltranslation.com/en-US/docs/core/types/jsx-element.mdx
---
title: JsxElement
description: Type definition for structured HTML-like elements in translatable JSX content
---
## Overview
`JsxElement` represents structured HTML-like elements in translatable JSX content.
```typescript
type JsxElement = {
t?: string; // tag name
i?: number; // id
d?: GTProp; // GT data/properties
c?: JsxChildren; // children
};
```
## Properties
| Property | Type | Description |
|----------|------|-------------|
| `t?` | `string` | HTML tag name |
| `i?` | `number` | Internal identifier |
| `d?` | `GTProp` | GT properties/attributes |
| `c?` | `JsxChildren` | Child content |
### Common GT keys
| GT Key | HTML Attribute |
|--------|----------------|
| `pl` | `placeholder` |
| `ti` | `title` |
| `alt` | `alt` |
| `arl` | `aria-label` |
## Examples
### Basic usage
```typescript copy
import { JsxElement, Variable } from 'generaltranslation';
// Simple element
const heading: JsxElement = {
t: 'h1',
c: ['Welcome']
};
// With attributes
const button: JsxElement = {
t: 'button',
d: { ti: 'Submit form' },
c: ['Submit']
};
```
## Related types
* [`JsxChildren`](/docs/core/types/jsx-children) - Children content type
* [`JsxChild`](/docs/core/types/jsx-child) - Individual child elements
# generaltranslation: General Translation Core SDK: LocaleProperties
URL: https://generaltranslation.com/en-US/docs/core/types/locale-properties.mdx
---
title: LocaleProperties
description: TypeScript interface containing comprehensive locale information
---
## Overview
`LocaleProperties` provides detailed linguistic and regional information about a locale.
```typescript
interface LocaleProperties {
code: string;
name: string;
nativeName: string;
languageCode: string;
languageName: string;
nativeLanguageName: string;
nameWithRegionCode: string;
nativeNameWithRegionCode: string;
regionCode: string;
regionName: string;
nativeRegionName: string;
scriptCode: string;
scriptName: string;
nativeScriptName: string;
maximizedCode: string;
maximizedName: string;
nativeMaximizedName: string;
minimizedCode: string;
minimizedName: string;
nativeMinimizedName: string;
emoji: string;
}
```
Returned by `getLocaleProperties` methods.
## Key properties
| Property | Description |
|----------|-------------|
| `code` | Original locale code |
| `name` | Display name in source language |
| `nativeName` | Display name in native language |
| `languageCode` | Base language code |
| `regionCode` | ISO region code |
| `scriptCode` | ISO script code |
| `maximizedCode` | Locale with likely script/region |
| `minimizedCode` | Shortest valid locale code |
| `emoji` | Flag emoji |
## Examples
### Basic usage
```typescript
const gt = new GT({ sourceLocale: 'en-US' });
const props = gt.getLocaleProperties('de-AT');
console.log(props.name); // "Austrian German"
console.log(props.nativeName); // "Österreichisches Deutsch"
console.log(props.emoji); // "🇦🇹"
```
## Related types
* [`getLocaleProperties`](/docs/core/class/methods/locales/get-locale-properties) - Method that returns this interface
# generaltranslation: General Translation Core SDK: TranslateManyResult
URL: https://generaltranslation.com/en-US/docs/core/types/translate-many-result.mdx
---
title: TranslateManyResult
description: Type definition for results returned by batch translation operations
---
## Overview
`TranslateManyResult` represents the result of batch translation operations with [`translateMany`](/docs/core/class/methods/translation/translate-many).
```typescript
type TranslateManyResult = TranslationResult[];
```
It is an array of [`TranslationResult`](/docs/core/types/translation-result) objects, maintaining the same order as the input entries.
## Structure
```typescript
type TranslationResult = RequestSuccess | TranslationError;
type RequestSuccess = TypedResult & {
success: true;
locale: string;
};
type TranslationError = {
success: false;
error: string;
code: number;
};
```
Each element is either a successful result or an error, discriminated via the `success` property.
## Examples
### Basic usage
```typescript copy
import { GT, TranslateManyResult } from 'generaltranslation';
const gt = new GT({
apiKey: 'your-api-key',
projectId: 'your-project-id'
});
const results: TranslateManyResult = await gt.translateMany(
['Hello', 'Goodbye'],
'es'
);
```
### Error handling
```typescript copy
results.forEach((result, index) => {
if (result.success) {
console.log(`Entry ${index}: ${result.translation}`);
} else {
console.error(`Entry ${index} failed: ${result.error}`);
}
});
```
## Related types
* [`TranslationResult`](/docs/core/types/translation-result) - Individual result structure
* [`translateMany`](/docs/core/class/methods/translation/translate-many) - Method that returns this type
# generaltranslation: General Translation Core SDK: TranslationResult
URL: https://generaltranslation.com/en-US/docs/core/types/translation-result.mdx
---
title: TranslationResult
description: Type definition for translation results returned by translate() methods
---
## Overview
`TranslationResult` represents the result of translation operations.
```typescript
type TranslationResult = RequestSuccess | TranslationError;
```
## Union types
### RequestSuccess
```typescript
type RequestSuccess = TypedResult & {
success: true;
locale: string;
};
```
### TranslationError
```typescript
type TranslationError = {
success: false;
error: string;
code: number;
};
```
## Examples
### Basic error handling
```typescript copy
import { GT, TranslationResult } from 'generaltranslation';
const gt = new GT({ apiKey: 'your-api-key' });
const result: TranslationResult = await gt.translate('Hello');
if (result.success) {
console.log(`Translation: ${result.translation}`);
} else {
console.error(`Translation failed: ${result.error}`);
}
```
### Using the discriminant
```typescript copy
if (result.success) {
// Handle success — result.translation is available
} else {
// Handle error — result.error and result.code are available
}
```
## Related types
* [`TranslateManyResult`](/docs/core/types/translate-many-result) - Batch translation results
# generaltranslation: General Translation Core SDK: VariableType
URL: https://generaltranslation.com/en-US/docs/core/types/variable-type.mdx
---
title: VariableType
description: Enumeration of variable formatting types for dynamic content translation
---
## Overview
`VariableType` specifies how variables are formatted in translated content.
```typescript
type VariableType = 'v' | 'n' | 'd' | 'c';
```
## Values
| Value | Description |
|-------|-------------|
| `'v'` | Plain text substitution |
| `'n'` | Number formatting |
| `'d'` | Date formatting |
| `'c'` | Currency formatting |
## Examples
### Basic usage
```typescript copy
import { Variable, VariableType } from 'generaltranslation';
const textVar: Variable = { k: 'name', v: 'v' };
const numberVar: Variable = { k: 'count', v: 'n' };
const dateVar: Variable = { k: 'date', v: 'd' };
const currencyVar: Variable = { k: 'price', v: 'c' };
```
## Related types
* [`Variable`](/docs/core/types/Variable) - Parent type using VariableType
# gt: General Translation CLI tool: Auto JSX Injection
URL: https://generaltranslation.com/en-US/docs/cli/features/auto-jsx-injection.mdx
---
title: Auto JSX Injection
description: Automatically wrap JSX text in translation components at build time
---
## Overview
With auto JSX injection enabled, the compiler automatically wraps translatable JSX text in `` translation components at build time — so you don't need to add them manually.
Auto JSX injection is **disabled by default**.
**Limitation:** Auto JSX injection currently only works with the i18n-context system and SPA React apps.
## Configuration
```json title="gt.config.json"
{
"files": {
"gt": {
"parsingFlags": {
"enableAutoJsxInjection": true
}
}
}
}
```
## Example
Without auto JSX injection:
```jsx
import { T } from 'gt-next';
function Welcome() {
return (
Welcome to our app
);
}
```
With auto JSX injection enabled:
```jsx
function Welcome() {
return Welcome to our app ;
}
```
The compiler detects the translatable text and wraps it automatically at build time. User-written `` components and other GT components like ``, ``, ``, and `` are left untouched.
## Related
- [Autoderive](/docs/cli/features/autoderive)
- [Release notes: compiler@1.3.0](/devlog/compiler_v1_3_0)
# gt: General Translation CLI tool: Autoderive
URL: https://generaltranslation.com/en-US/docs/cli/features/autoderive.mdx
---
title: Autoderive
description: Automatically derive interpolated values in translation functions and JSX components
---
## Overview
When autoderive is enabled, interpolated values are parsed as if they were wrapped in [`derive()`](/docs/next/api/strings/derive). This generates separate translation entries for each possible value, preserving word agreement and conjugation across languages.
Autoderive works in two contexts:
- **Strings** — interpolated values in `t()`, `gt()`, and `msg()` calls
- **JSX** — expressions inside `` components that reference const variable declarations
Autoderive is **disabled by default**.
## Configuration
Enable autoderive for both strings and JSX:
```json title="gt.config.json"
{
"files": {
"gt": {
"parsingFlags": {
"autoderive": true
}
}
}
}
```
You can also enable autoderive selectively for just strings or just JSX:
```json title="gt.config.json"
{
"files": {
"gt": {
"parsingFlags": {
"autoderive": { "jsx": true, "strings": false }
}
}
}
}
```
## String example
```jsx
const gt = useGT();
const role = isAdmin ? "admin" : "user";
// With autoderive enabled, this is parsed as derived:
gt(`Welcome back, ${role}!`);
// Generates:
// "Welcome back, admin!" → "¡Bienvenido de nuevo, administrador!"
// "Welcome back, user!" → "¡Bienvenido de nuevo, usuario!"
```
Without autoderive, you must explicitly use [`derive()`](/docs/next/api/strings/derive) to get the same behavior.
## JSX example
```jsx
const label = condition ? "boy" : "girl";
Hello, {label}
// Generates two translation entries:
// "Hello, boy" → "Hola, chico"
// "Hello, girl" → "Hola, chica"
```
JSX autoderive resolves `const` variable declarations referenced inside `` components. It supports:
- Ternary expressions (`const x = cond ? "a" : "b"`)
- Nested ternaries (`const x = a ? "small" : b ? "medium" : "large"`)
- String, number, and boolean literals
- String concatenation and template literals
- Chained const references (`const alias = base`)
**`const` only:** Only `const` declarations are supported. `let` and `var` variables produce a warning because they can be reassigned. Destructured variables (`const { x } = obj`) are not supported.
**Note:** The `t` tagged template macro is unaffected — it handles derivation through its template literal syntax.
## Related
- [`derive()` function reference](/docs/next/api/strings/derive)
- [Auto JSX injection](/docs/cli/features/auto-jsx-injection)
- [Release notes: gt@2.13.0](/devlog/gt_v2_13_0)
# gt: General Translation CLI tool: GT JSX
URL: https://generaltranslation.com/en-US/docs/cli/formats/gt.mdx
---
title: GT JSX
description: Automatically translate your gt-next, gt-react, or gt-react-native project
---
## Overview
This tutorial will show you how to automatically manage your project's translation files when using [`gt-next`](/docs/next), [`gt-react`](/docs/react), or [`gt-react-native`](/docs/react-native).
**Note:** This should only be used when you are shipping a production build.
If you are using gt-next, gt-react, or gt-react-native in development, this
command is not needed.
We will follow these 3 steps:
Add your environment variables
Configure your project with the [`npx gt
configure`](/docs/cli/configure) command
Run [`gt translate`](/docs/cli/translate#translate)
---
## Step 1: Add your environment variables
Add your production API key and project ID to your environment variables.
This is necessary to use the `gt` tool.
You get these from the [General Translation dashboard](https://generaltranslation.com/dashboard).
```bash title=".env"
GT_API_KEY=
GT_PROJECT_ID=
```
## Step 2: Configure your project with the `npx gt configure` command
Run the `gt configure` command to configure your project.
```bash
npx gt configure
```
## Step 3: Add the `gt translate` command to your build process
Add the `gt translate` command to your build or CI process before the build command to automatically add translations to your project.
```json title="package.json"
{
"scripts": {
"translate": "npx gt translate",
"build": "npm run translate && "
}
}
```
This will generate translations for all of your locales and save them to your project.
If you want to commit these files to your repo, you can instead run this command before committing.
You're done! Now your project will automatically update all of your translation JSON files any time your project changes.
---
## Notes
- You can automatically add translations to your project with the [`gt translate`](/docs/cli/translate#translate) command.
- If you want to commit your translation files, you can instead run the `gt translate` command before committing.
- To configure the output path for your translations, see the [configuration](/docs/cli/reference/config) docs.
## Next steps
- See the [translate command](/docs/cli/translate) for CLI usage details.
# gt: General Translation CLI tool: HTML
URL: https://generaltranslation.com/en-US/docs/cli/formats/html.mdx
---
title: HTML
description: How to use General Translation to set up automatic translation for HTML files
---
## Overview
`gt` can be used to automatically translate HTML files.
All syntax and formatting present in the original files will be preserved in
the translated files.
We will follow these 4 steps:
Add your environment variables
Install [`gt`](/docs/cli)
Configure your project's [`gt.config.json`](/docs/cli/reference/config) file
Run [`gt translate`](/docs/cli/translate#translate)
---
## Step 1: Add your environment variables
Add your production API key and project ID to your environment variables.
This is necessary to use the `gt` tool.
You get these from the [General Translation dashboard](https://generaltranslation.com/dashboard).
```bash title=".env"
GT_API_KEY=
GT_PROJECT_ID=
```
## Step 2: Install `gt`
Install the `gt` tool in your project.
```bash
npm i gt
```
```bash
yarn add --dev gt
```
```bash
bun add --dev gt
```
```bash
pnpm add --save-dev gt
```
## Step 3: Configure your project's `gt.config.json` file
Create a `gt.config.json` file in the root of your project, with the following content:
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["es", "fr"],
"files": {
"html": {
"include": ["docs/[locale]/**/*.html"]
}
}
}
```
Change the `defaultLocale` and `locales` to match your project's locales.
The string array in the `include` key should be a glob pattern that matches all of your HTML files.
It should use the `[locale]` placeholder to match the locale of the file.
See the [configuration](/docs/cli/reference/config) docs for more information on the `gt.config.json` file.
## Step 4: Add the `gt translate` command to your build process
Add the `gt translate` command to your build or CI process before the build command to automatically add translations to your project.
```json title="package.json"
{
"scripts": {
"translate": "npx gt translate",
"build": "npm run translate && "
}
}
```
This will generate translations for all of your locales and save them to your project.
If you want to commit these files to your repo, you can instead run this command before committing.
You're done! Now your project will automatically update all of your HTML files any time your project changes.
---
## Notes
- You can automatically add translations to your project with the [`gt translate`](/docs/cli/translate) command.
- If you want to commit your translation files, you should run the `gt translate` command before committing.
- To configure the output path for your translations, see the [configuration](/docs/cli/reference/config) docs.
## Next steps
- See the [translate command](/docs/cli/translate) for CLI usage details.
# gt: General Translation CLI tool: JSON
URL: https://generaltranslation.com/en-US/docs/cli/formats/json.mdx
---
title: JSON
description: How to automatically translate JSON files with General Translation
---
## Overview
`gt` can be used to automatically translate your project's JSON files, regardless of what i18n library you are using.
**Note:** We currently support custom string syntax and formatting for the
following 3rd-party i18n libraries: `next-intl`, `i18next`. If you are using a
different i18n library, the translation results may not be accurate for
strings with custom syntax and formatting (for example, ICU messages). Don't
see your favorite library? [Please let us
know](https://github.com/generaltranslation/gt/issues), and we will add it as
soon as we can!
We will follow these 4 steps:
Add your environment variables
Install [`gt`](/docs/cli)
Create a `gt.config.json` file
Run [`gt translate`](/docs/cli/translate#translate)
**Tip:**
Avoid the hassle of using translation files with the [`` component](/docs/react/guides/t).
---
## Step 1: Add your environment variables
Add your production API key and project ID to your environment variables.
This is necessary to use the `gt` tool.
You get these from the [General Translation dashboard](https://generaltranslation.com/dashboard).
```bash title=".env"
GT_API_KEY=
GT_PROJECT_ID=
```
## Step 2: Install `gt`
Install the `gt` tool in your project.
```bash
npm i gt
```
```bash
yarn add --dev gt
```
```bash
bun add --dev gt
```
```bash
pnpm add --save-dev gt
```
## Step 3: Create a `gt.config.json` file
Create a `gt.config.json` file in the root of your project.
```json title="gt.config.json" copy
{
"defaultLocale": "en",
"locales": ["zh", "es", "ja"],
"files": {
"json": {
"include": ["i18n/[locale]/*.json"]
}
}
}
```
Feel free to customize the `gt.config.json` file to your needs. See the [configuration](/docs/cli/reference/config) docs for more information.
Update the `json` file format such that the `include` path matches your project structure.
Translations will preserve the original string syntax.
## Step 4: Add the `gt translate` command to your build process
Add the `gt translate` command to your build or CI process before the build command to automatically add translations to your project.
```json title="package.json"
{
"scripts": {
"translate": "npx gt translate",
"build": "npm run translate && "
}
}
```
This will generate translations for all of your locales and save them to your project.
If you want to commit these files to your repo, you can instead run this command before committing.
You're done! Now your project will automatically update all of your translation JSON files any time your project changes.
---
## Keyed metadata
You can attach per-key translation instructions to individual strings using a companion `.metadata.json` file. This lets you provide context, character limits, and source code context for specific keys without modifying the source file.
```json title="translations.json"
{
"nav": {
"home": "Home",
"bank": "Bank",
"save": "Save"
}
}
```
```json title="translations.metadata.json"
{
"nav": {
"bank": {
"context": "Riverbank — the side of a river. NOT a financial institution."
},
"save": {
"context": "Sports term — a goalkeeper preventing a goal. NOT saving data.",
"maxChars": 12
}
}
}
```
Not every key needs metadata — only provide entries for keys that need specific translation instructions.
See the [keyed metadata reference](/docs/cli/reference/keyed-metadata) for the full list of supported fields.
---
## Notes
- You can automatically add translations to your project with the [`gt translate`](/docs/cli/translate#translate) command.
- If you want to commit your translation files, you should run the `gt translate` command before committing.
- To configure the output path for your translations, see the [configuration](/docs/cli/reference/config) docs.
## Next steps
- See the [translate command](/docs/cli/translate) for CLI usage details.
- Learn about [keyed metadata](/docs/cli/reference/keyed-metadata) for per-key translation instructions.
# gt: General Translation CLI tool: Markdown
URL: https://generaltranslation.com/en-US/docs/cli/formats/mdx.mdx
---
title: Markdown
description: How to use General Translation to set up automatic translation for your project's Markdown files
---
## Overview
`gt` can be used to automatically translate your project's Markdown (MD and MDX) files.
All syntax and formatting present in the original files will be preserved in
the translated files.
We will follow these 4 steps:
Add your environment variables
Install [`gt`](/docs/cli)
Configure your project's [`gt.config.json`](/docs/cli/reference/config) file
Run [`gt translate`](/docs/cli/translate#translate)
---
## Step 1: Add your environment variables
Add your production API key and project ID to your environment variables.
This is necessary to use the `gt` tool.
You get these from the [General Translation dashboard](https://generaltranslation.com/dashboard).
```bash title=".env"
GT_API_KEY=
GT_PROJECT_ID=
```
## Step 2: Install `gt`
Install the `gt` tool in your project.
```bash
npm i gt
```
```bash
yarn add --dev gt
```
```bash
bun add --dev gt
```
```bash
pnpm add --save-dev gt
```
## Step 3: Configure your project's `gt.config.json` file
Create a `gt.config.json` file in the root of your project, with the following content:
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["es", "fr"],
"files": {
"mdx": {
"include": ["docs/[locale]/**/*.mdx"]
}
}
}
```
If your files are MD files, you can use the `md` key instead of `mdx`.
Change the `defaultLocale` and `locales` to match your project's locales.
The string array in the `include` key should be a glob pattern that matches all of your MDX files.
It should use the `[locale]` placeholder to match the locale of the file.
See the [configuration](/docs/cli/reference/config) docs for more information on the `gt.config.json` file.
## Step 4: Add the `gt translate` command to your build process
Add the `gt translate` command to your build or CI process before the build command to automatically add translations to your project.
```json title="package.json"
{
"scripts": {
"translate": "npx gt translate",
"build": "npm run translate && "
}
}
```
This will generate translations for all of your locales and save them to your project.
If you want to commit these files to your repo, you can instead run this command before committing.
You're done! Now your project will automatically update all of your Markdown files any time your project changes.
---
## Notes
- You can automatically add translations to your project with the [`gt translate`](/docs/cli/translate) command.
- If you want to commit your translation files, you should run the `gt translate` command before committing.
- To configure the output path for your translations, see the [configuration](/docs/cli/reference/config) docs.
## Next steps
- See the [translate command](/docs/cli/translate) for CLI usage details.
# gt: General Translation CLI tool: PO / POT
URL: https://generaltranslation.com/en-US/docs/cli/formats/po.mdx
---
title: PO / POT
description: How to automatically translate PO/POT files with General Translation
---
## Overview
`gt` can be used to automatically translate your project's [PO (Portable Object)](https://www.gnu.org/software/gettext/manual/html_node/PO-Files.html) and POT (PO Template) files. These are the standard file format used by [GNU gettext](https://www.gnu.org/software/gettext/), one of the oldest and most widely adopted internationalization systems.
POT files contain the source strings extracted from your code, and PO files contain the translations for a specific locale.
We will follow these 4 steps:
Add your environment variables
Install [`gt`](/docs/cli)
Create a `gt.config.json` file
Run [`gt translate`](/docs/cli/translate#translate)
---
## Step 1: Add your environment variables
Add your production API key and project ID to your environment variables.
This is necessary to use the `gt` tool.
You get these from the [General Translation dashboard](https://generaltranslation.com/dashboard).
```bash title=".env"
GT_API_KEY=
GT_PROJECT_ID=
```
## Step 2: Install `gt`
Install the `gt` tool in your project.
```bash
npm i gt
```
```bash
yarn add --dev gt
```
```bash
bun add --dev gt
```
```bash
pnpm add --save-dev gt
```
## Step 3: Create a `gt.config.json` file
Create a `gt.config.json` file in the root of your project.
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["zh", "es", "ja"],
"files": {
"pot": {
"include": ["locales/[locale]/*.pot"],
"transformationFormat": "PO"
}
}
}
```
Feel free to customize the `gt.config.json` file to your needs. See the [configuration](/docs/cli/reference/config) docs for more information.
Update the `pot` file format such that the `include` path matches your project structure.
The `transformationFormat` option tells `gt` to output translated files as `.po` files instead of `.pot` files. This is the standard workflow: POT files are source templates, and PO files contain the actual translations for each locale.
**Note:** Translations will preserve the original PO/POT string syntax.
## Step 4: Add the `gt translate` command to your build process
Add the `gt translate` command to your build or CI process before the build command to automatically add translations to your project.
```json title="package.json"
{
"scripts": {
"translate": "npx gt translate",
"build": "npm run translate && "
}
}
```
This will generate translations for all of your locales and save them to your project.
If you want to commit these files to your repo, you can instead run this command before committing.
You're done! Now your project will automatically update all of your translation PO/POT files any time your project changes.
---
## Notes
- You can automatically add translations to your project with the [`gt translate`](/docs/cli/translate#translate) command.
- If you want to commit your translation files, you should run the `gt translate` command before committing.
- To configure the output path for your translations, see the [configuration](/docs/cli/reference/config) docs.
- Both `pot` and `POT` are accepted as the config key in `gt.config.json`.
## Next steps
- See the [translate command](/docs/cli/translate) for CLI usage details.
- Learn about [keyed metadata](/docs/cli/reference/keyed-metadata) for per-key translation instructions.
# gt: General Translation CLI tool: TypeScript
URL: https://generaltranslation.com/en-US/docs/cli/formats/ts.mdx
---
title: TypeScript
description: How to automatically translate TypeScript and JavaScript files with General Translation
---
## Overview
`gt` can be used to automatically translate your project's JavaScript (js) and TypeScript (ts) files.
All syntax and formatting present in the original files will be preserved in
the translated files.
We will follow these 4 steps:
Add your environment variables
Install [`gt`](/docs/cli)
Configure your project's [`gt.config.json`](/docs/cli/reference/config) file
Run [`gt translate`](/docs/cli/translate#translate)
---
## Step 1: Add your environment variables
Add your production API key and project ID to your environment variables.
This is necessary to use the `gt` tool.
You get these from the [General Translation dashboard](https://generaltranslation.com/dashboard).
```bash title=".env"
GT_API_KEY=
GT_PROJECT_ID=
```
## Step 2: Install `gt`
Install the `gt` tool in your project.
```bash
npm i gt
```
```bash
yarn add --dev gt
```
```bash
bun add --dev gt
```
```bash
pnpm add --save-dev gt
```
## Step 3: Configure your project's `gt.config.json` file
Create a `gt.config.json` file in the root of your project, with the following content:
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["es", "fr"],
"files": {
"ts": {
"include": ["docs/[locale]/**/*.ts"]
}
}
}
```
Change the `defaultLocale` and `locales` to match your project's locales.
If your files are JavaScript files, you can use the `js` key instead of `ts`. The string array in the `include` key should be a glob pattern that matches all of your JS files.
It should use the `[locale]` placeholder to match the locale of the file.
See the [configuration](/docs/cli/reference/config) docs for more information on the `gt.config.json` file.
## Step 4: Add the `gt translate` command to your build process
Add the `gt translate` command to your build or CI process before the build command to automatically add translations to your project.
```json title="package.json"
{
"scripts": {
"translate": "npx gt translate",
"build": "npm run translate && "
}
}
```
This will generate translations for all of your locales and save them to your project.
If you want to commit these files to your repo, you can instead run this command before committing.
You're done! Now your project will automatically update all of your TypeScript files any time your project changes.
---
## Notes
- You can automatically add translations to your project with the [`gt translate`](/docs/cli/translate) command.
- If you want to commit your translation files, you should run the `gt translate` command before committing.
- To configure the output path for your translations, see the [configuration](/docs/cli/reference/config) docs.
## Next steps
- See the [translate command](/docs/cli/translate) for CLI usage details.
# gt: General Translation CLI tool: Text
URL: https://generaltranslation.com/en-US/docs/cli/formats/txt.mdx
---
title: Text
description: How to use General Translation to set up automatic translation for your project's text files
---
## Overview
`gt` can be used to automatically translate any arbitrary text files.
We will follow these 4 steps:
Add your environment variables
Install [`gt`](/docs/cli)
Configure your project's [`gt.config.json`](/docs/cli/reference/config) file
Run [`gt translate`](/docs/cli/translate#translate)
---
## Step 1: Add your environment variables
Add your production API key and project ID to your environment variables.
This is necessary to use the `gt` tool.
You get these from the [General Translation dashboard](https://generaltranslation.com/dashboard).
```bash title=".env"
GT_API_KEY=
GT_PROJECT_ID=
```
## Step 2: Install `gt`
Install the `gt` tool in your project.
```bash
npm i gt
```
```bash
yarn add --dev gt
```
```bash
bun add --dev gt
```
```bash
pnpm add --save-dev gt
```
## Step 3: Configure your project's `gt.config.json` file
Create a `gt.config.json` file in the root of your project, with the following content:
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["es", "fr"],
"files": {
"txt": {
"include": ["docs/[locale]/**/*.txt"]
}
}
}
```
Change the `defaultLocale` and `locales` to match your project's locales.
The string array in the `include` key should be a glob pattern that matches all of your text files.
It should use the `[locale]` placeholder to match the locale of the file.
See the [configuration](/docs/cli/reference/config) docs for more information on the `gt.config.json` file.
## Step 4: Add the `gt translate` command to your build process
Add the `gt translate` command to your build or CI process before the build command to automatically add translations to your project.
```json title="package.json"
{
"scripts": {
"translate": "npx gt translate",
"build": "npm run translate && "
}
}
```
This will generate translations for all of your locales and save them to your project.
If you want to commit these files to your repo, you can instead run this command before committing.
You're done! Now your text files will be automatically translated any time your source files change.
---
## Notes
- You can automatically add translations to your project with the [`gt translate`](/docs/cli/translate) command.
- If you want to commit your translation files, you should run the `gt translate` command before committing.
- To configure the output path for your translations, see the [configuration](/docs/cli/reference/config) docs.
## Next steps
- See the [translate command](/docs/cli/translate) for CLI usage details.
# gt: General Translation CLI tool: YAML
URL: https://generaltranslation.com/en-US/docs/cli/formats/yaml.mdx
---
title: YAML
description: How to automatically translate YAML files with General Translation
---
## Overview
`gt` can be used to automatically translate your project's YAML files, regardless of what i18n library you are using.
**Note:** We currently support custom string syntax and formatting for the
following 3rd-party i18n libraries: `next-intl`, `i18next`. If you are using a
different i18n library, the translation results may not be accurate for
strings with custom syntax and formatting (for example, ICU messages). Don't
see your favorite library? [Please let us
know](https://github.com/generaltranslation/gt/issues), and we will add it as
soon as we can!
We will follow these 4 steps:
Add your environment variables
Install [`gt`](/docs/cli)
Create a `gt.config.json` file
Run [`gt translate`](/docs/cli/translate#translate)
---
## Step 1: Add your environment variables
Add your production API key and project ID to your environment variables.
This is necessary to use the `gt` tool.
You get these from the [General Translation dashboard](https://generaltranslation.com/dashboard).
```bash title=".env"
GT_API_KEY=
GT_PROJECT_ID=
```
## Step 2: Install `gt`
Install the `gt` tool in your project.
```bash
npm i gt
```
```bash
yarn add --dev gt
```
```bash
bun add --dev gt
```
```bash
pnpm add --save-dev gt
```
## Step 3: Create a `gt.config.json` file
Create a `gt.config.json` file in the root of your project.
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["zh", "es", "ja"],
"files": {
"yaml": {
"include": ["i18n/[locale]/*.yaml"]
}
}
}
```
Feel free to customize the `gt.config.json` file to your needs. See the [configuration](/docs/cli/reference/config) docs for more information.
Update the `yaml` file format such that the `include` path matches your project structure. Both `.yaml` and `.yml` extensions are supported.
Translations will preserve the original string syntax.
## Step 4: Add the `gt translate` command to your build process
Add the `gt translate` command to your build or CI process before the build command to automatically add translations to your project.
```json title="package.json"
{
"scripts": {
"translate": "npx gt translate",
"build": "npm run translate && "
}
}
```
This will generate translations for all of your locales and save them to your project.
If you want to commit these files to your repo, you can instead run this command before committing.
You're done! Now your project will automatically update all of your translation YAML files any time your project changes.
---
## Keyed metadata
You can attach per-key translation instructions to individual strings using a companion `.metadata.yaml` file. This lets you provide context, character limits, and source code context for specific keys without modifying the source file.
```yaml title="translations.yaml"
nav:
home: "Home"
bank: "Bank"
save: "Save"
alerts:
new_lead: "You have a new lead!"
```
```yaml title="translations.metadata.yaml"
nav:
bank:
context: "Riverbank — the side of a river. NOT a financial institution."
save:
context: "Sports term — a goalkeeper preventing a goal. NOT saving data."
maxChars: 12
alerts:
new_lead:
context: "Sales/CRM context. A 'lead' is a potential customer."
maxChars: 30
```
Not every key needs metadata — only provide entries for keys that need specific translation instructions.
See the [keyed metadata reference](/docs/cli/reference/keyed-metadata) for the full list of supported fields.
---
## Notes
- You can automatically add translations to your project with the [`gt translate`](/docs/cli/translate#translate) command.
- If you want to commit your translation files, you should run the `gt translate` command before committing.
- To configure the output path for your translations, see the [configuration](/docs/cli/reference/config) docs.
- Both `.yaml` and `.yml` extensions are supported.
## Next steps
- See the [translate command](/docs/cli/translate) for CLI usage details.
- Learn about [keyed metadata](/docs/cli/reference/keyed-metadata) for per-key translation instructions.
# gt: General Translation CLI tool: Configuration
URL: https://generaltranslation.com/en-US/docs/cli/reference/config.mdx
---
title: Configuration
description: Config docs for the gt.config.json file
---
## Overview
The `gt.config.json` file is used to configure your project's GT settings. It should be placed in the root of your project.
The CLI setup wizard [`npx gt init`](/docs/cli/init) will create a `gt.config.json` file for you in your project.
## Configuration
The `gt.config.json` file accepts the following properties, but is not limited to them:
- `defaultLocale`: The default locale for your project. This is the locale that your source content is written in. This is also the fallback locale for your project (if using `gt-next` or `gt-react`).
- `locales`: An array of locales for your project. These are the locales that you want to translate your project into. See the [supported locales](/docs/platform/supported-locales) for more information.
If you are using `gt-next` or `gt-react`, these are also the locales that your app supports.
- `files`: This is an object that contains information about the content you want to translate.
- `publish`: An optional boolean flag. When `true`, translated files are published to the GT CDN after running `translate`, `upload`, or `save-local`. Defaults to `false` (no publishing). Can also be set per-command with `--publish`. See [CDN publishing](#cdn-publishing) for details.
- `stageTranslations`: An optional boolean flag that indicates whether your project is configured to use human review.
- `src`: An optional array of file glob patterns for your source files. By default, set to:
```json
[
"src/**/*.{js,jsx,ts,tsx}",
"app/**/*.{js,jsx,ts,tsx}",
"pages/**/*.{js,jsx,ts,tsx}",
"components/**/*.{js,jsx,ts,tsx}"
]
```
- `dictionary`: An optional string that specifies the relative path to the dictionary file.
- `branchOptions`: An optional object for configuring branch-based translation tracking. See [branching](/docs/cli/branching) for more details.
To help validate your `gt.config.json` file, you can use the [JSON Schema](https://assets.gtx.dev/config-schema.json) for the CLI.
Add it to the top of your `gt.config.json` file:
```json title="gt.config.json" copy
{
"$schema": "https://assets.gtx.dev/config-schema.json"
}
```
Here is a skeleton of the `gt.config.json` file:
```json title="gt.config.json"
{
"$schema": "https://assets.gtx.dev/config-schema.json",
"defaultLocale": "en",
"locales": ["fr", "es"],
"files": {
"gt": {
"output": "..."
},
"json": {
"include": [...]
},
"mdx": {
"include": [...]
},
"md": {
"include": [...]
}
},
"src": [
"src/**/*.{ts,tsx}",
],
"dictionary": "./dictionary.json"
}
```
### Locale aliasing
In the case you want to alias a locale (e.g. `cn` instead of `zh`), you can specify a custom mapping in the `gt.config.json` file.
```json title="gt.config.json"
{
"customMapping": {
// The alias locale
"cn": {
"code": "zh" // The official BCP 47 locale code
}
}
}
```
You can also specify different attributes for the aliased locale.
```json title="gt.config.json"
{
"customMapping": {
"cn": {
"code": "zh",
"name": "Mandarin"
}
}
}
```
### Branch options
If you want to configure branching settings in your config file, you can use the `branchOptions` object:
```json title="gt.config.json"
{
"branchOptions": {
"enabled": true,
"currentBranch": "my-feature-branch",
"autoDetectBranches": true,
"remoteName": "origin"
}
}
```
| Property | Description | Default |
| -------------------- | ----------------------------------------------------------------------------- | ----------- |
| `enabled` | Enable branching for the project | `false` |
| `currentBranch` | Override the current branch name (instead of auto-detect) | `undefined` |
| `autoDetectBranches` | Automatically detect branch relationships (incoming and checked-out branches) | `true` |
| `remoteName` | The git remote name used for branch detection | `"origin"` |
CLI flags take precedence over config file options. See the [branching guide](/docs/cli/branching) for more details.
---
## `files`
### Supported file types
`files` should contain a key for each file type that you want to translate.
You can configure your project to mix and match different file types, and have them all be translated.
We currently support the following file types:
- `gt`: General Translation files. Used by [`gt-next`](/docs/next), [`gt-react`](/docs/react), and [`gt-react-native`](/docs/react-native).
- `json`: JSON files.
- `pot`: PO/POT (gettext) files.
- `yaml`: YAML files.
- `mdx`: Markdown component (MDX) files.
- `md`: Markdown (MD) files.
- `js`: JavaScript files.
- `ts`: TypeScript files.
- `html`: HTML files.
- `txt`: Text files.
- `twilioContentJson`: Twilio Content JSON files. Used for translating [Twilio Content Templates](https://www.twilio.com/docs/content).
Each file type should correspond to an object that contains one or more of the following keys:
- `include`
- `exclude`
- `transform`
- `transformationFormat`
- `output`
### `include`
If used, the value of the `include` key should be an array of glob patterns that match the files you want to translate.
You must use the `[locale]` placeholder in your glob patterns to ensure that source files are found correctly, and translated files are saved to the correct location.
The CLI tool will replace the `[locale]` placeholder with the `defaultLocale` value when searching for translatable files.
The CLI tool will save translated files to the corresponding path, with the `[locale]` placeholder replaced with the target locale code.
```json
{
"include": ["docs/[locale]/**/*.json"]
}
```
### `exclude`
If used, the value of the `exclude` key should be an array of glob patterns that match the files you want to exclude from translation.
The pattern is the same as the `include` pattern, with the exception that the `[locale]` placeholder is optional. If provided, it will be replaced with the `defaultLocale` value.
```json
{
"exclude": ["docs/[locale]/exclude/**/*.json"]
}
```
If you want to exclude files from translation for all locales, you can use the `[locales]` placeholder instead of `[locale]`.
```json
{
"exclude": ["docs/[locales]/exclude/**/*.json"]
}
```
### `transform`
`transform` can either be a string or an object.
If `transform` is a string, it defines a remapping of the file name. It should contain a wildcard `*` that will be replaced with the original file name (anything before the first `.`).
For example, if you want the extension of all of your translated files to have `.[locale].json` instead of `.json`, you can use the following configuration:
```json
{
"transform": "*.[locale].json"
}
```
Alternatively, if `transform` is an object, it should contain the following properties:
- `match` (optional): A regex pattern to match strings, supports capture groups
- `replace` (required): String or regex pattern to replace the match with
Both values support regex capture groups and are mapped to the full relative file name of the output file.
```json
{
"transform": {
"match": "^(.*)$",
"replace": "{locale}/$1"
}
}
```
For example, the above configuration will cause translated files to be saved under a target locale subdirectory.
#### Special placeholders
The transform option supports several special placeholders that can be used in both `match` and `replace` strings:
- `{locale}`: The locale code placeholder that behaves differently depending on context:
- **In `match` strings**: Replaced with the default locale code (e.g., `"en"`) to help identify source files
- **In `replace` strings**: Replaced with the target locale code (e.g., `"fr"`, `"es"`) for the translated output files
For example, if your default locale is `"en"` and you're translating to `"fr"`:
- A `match` pattern of `"content/{locale}/file.md"` becomes `"content/en/file.md"`
- A `replace` pattern of `"content/{locale}/file.md"` becomes `"content/fr/file.md"`
Additionally, any other property from `getLocaleProperties` can be used as a placeholder with the same context-dependent behavior.
This is useful if your docs or i18n framework requires a specific file extension for translated files instead of subdirectory-based locale routing.
### `transformationFormat`
The `transformationFormat` key specifies a different file format for the translated output files. This is useful when your source files are templates that should produce a different file type after translation.
For example, POT (PO Template) files are source templates, but the translated output should be PO files:
```json
{
"files": {
"pot": {
"include": ["locales/[locale]/**/*.pot"],
"transformationFormat": "PO"
}
}
}
```
The value should be a string matching one of the supported file format keys (e.g., `"PO"`).
### `output`
This key is exclusively used for General Translation files, specifically for saving translations locally. If you are using the GT CDN, this key is not needed.
The value should be a string containing a `[locale]` placeholder indicating the location where the translations will be saved.
For example, if you want to your Spanish translations to a file called `ui.es.json` in the `public/i18n` directory, you should use the following string:
```json
{
"output": "public/i18n/[locale].json"
}
```
This option should only be used if you are using `gt-next` or `gt-react`, and want to save translations locally, instead of using the GT CDN.
Currently, only one file for each locale can be generated.
---
### File type: `gt` [#gt]
**Supported Keys**
- `output` (Required)
**Example**
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["fr", "es"],
"files": {
"gt": {
"output": "public/i18n/[locale].json"
}
}
}
```
This configuration will tell the CLI tool to save your French and Spanish translations to the `public/i18n/[locale].json` directory.
By default, the CLI tool will not publish your translations to the GT CDN with this configuration.
---
### File type: `json` [#json]
**Supported Keys**
- `include` (Required)
- `exclude` (Optional)
- `transform` (Optional)
**Example**
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["fr", "es"],
"files": {
"json": {
"include": ["json_files/[locale]/**/*.json"],
"exclude": ["json_files/[locale]/exclude/**/*.json"]
}
}
}
```
Let's say your project's default locale is `en`, and you want to translate your project into `fr` and `es`.
With this configuration, the CLI will search for all JSON files under the subdirectory `json_files/en/` and save the translated files to `json_files/fr/` and `json_files/es/`.
It will ignore any files in the subdirectory `json_files/en/exclude/`.
---
### File type: `yaml` [#yaml]
**Supported Keys**
- `include` (Required)
- `exclude` (Optional)
- `transform` (Optional)
**Example**
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["fr", "es"],
"files": {
"yaml": {
"include": ["yaml_files/[locale]/**/*.yaml"],
"exclude": ["yaml_files/[locale]/exclude/**/*.yaml"]
}
}
}
```
Let's say your project's default locale is `en`, and you want to translate your project into `fr` and `es`.
With this configuration, the CLI will search for all YAML files under the subdirectory `yaml_files/en/` and save the translated files to `yaml_files/fr/` and `yaml_files/es/`.
It will ignore any files in the subdirectory `yaml_files/en/exclude/`.
---
### File type: `mdx` [#mdx]
**Supported Keys**
- `include` (Required)
- `exclude` (Optional)
- `transform` (Optional)
**Example**
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["ja"],
"files": {
"mdx": {
"include": ["content/docs/[locale]/**/*.mdx"],
"transform": "*.[locale].mdx"
}
}
}
```
This configuration will tell the CLI tool to search for all MDX files under the `content/docs/en` directory and save the translated files to the `content/docs/ja` directory.
The `transform` key causes the extension of the translated files to be changed to `.ja.mdx`.
---
### File type: `md` [#md]
**Supported Keys**
- `include` (Required)
- `exclude` (Optional)
- `transform` (Optional)
**Example**
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["ja"],
"files": {
"md": {
"include": ["content/docs/[locale]/**/*.md"],
"exclude": ["content/docs/[locale]/exclude/**/*.md"],
"transform": "*.[locale].md"
}
}
}
```
This configuration will tell the CLI tool to search for all MD files under the `content/docs/en` directory and save the translated files to the `content/docs/ja` directory.
The `transform` key causes the extension of the translated files to be changed to `.ja.md`.
All files in the `content/docs/en/exclude` directory will be ignored.
---
### File type: `js` [#js]
**Supported Keys**
- `include` (Required)
- `exclude` (Optional)
- `transform` (Optional)
**Example**
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["fr", "es"],
"files": {
"js": {
"include": ["scripts/[locale]/**/*.js"]
}
}
}
```
This configuration will tell the CLI tool to search for all JavaScript files under the `scripts/en` directory and save the translated files to the `scripts/fr` and `scripts/es` directories.
---
### File type: `ts` [#ts]
**Supported Keys**
- `include` (Required)
- `exclude` (Optional)
- `transform` (Optional)
**Example**
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["fr", "es"],
"files": {
"ts": {
"include": ["scripts/[locale]/**/*.ts"]
}
}
}
```
This configuration will tell the CLI tool to search for all TypeScript files under the `scripts/en` directory and save the translated files to the `scripts/fr` and `scripts/es` directories.
---
### File type: `html` [#html]
**Supported Keys**
- `include` (Required)
- `exclude` (Optional)
- `transform` (Optional)
**Example**
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["ja"],
"files": {
"html": {
"include": ["content/docs/[locale]/**/*.html"],
"exclude": ["content/docs/[locale]/exclude/**/*.html"],
"transform": "*.[locale].html"
}
}
}
```
This configuration will tell the CLI tool to search for all HTML files under the `content/docs/en` directory and save the translated files to the `content/docs/ja` directory.
The `transform` key causes the extension of the translated files to be changed to `.ja.html`.
All files in the `content/docs/en/exclude` directory will be ignored.
---
### File type: `txt` [#txt]
**Supported Keys**
- `include` (Required)
- `exclude` (Optional)
- `transform` (Optional)
**Example**
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["ja"],
"files": {
"txt": {
"include": ["content/docs/[locale]/**/*.txt"],
"exclude": ["content/docs/[locale]/exclude/**/*.txt"],
"transform": "*.[locale].txt"
}
}
}
```
This configuration will tell the CLI tool to search for all text files under the `content/docs/en` directory and save the translated files to the `content/docs/ja` directory.
The `transform` key causes the extension of the translated files to be changed to `.ja.txt`.
All files in the `content/docs/en/exclude` directory will be ignored.
---
### File type: `twilioContentJson` [#twilioContentJson]
**Supported Keys**
- `include` (Required)
- `exclude` (Optional)
- `transform` (Optional)
**Example**
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["es", "fr"],
"files": {
"twilioContentJson": {
"include": ["twilio/[locale]/**/*.json"]
}
}
}
```
This configuration will tell the CLI tool to search for all Twilio Content JSON files under the `twilio/en` directory and save the translated files to the `twilio/es` and `twilio/fr` directories.
Twilio Content JSON files are structured templates used by [Twilio's Content Template Builder](https://www.twilio.com/docs/content) for WhatsApp, SMS, and RCS messaging. The CLI translates the user-facing string values (body text, button labels, card titles) while preserving the template structure, variable placeholders, and non-translatable fields.
---
## CDN publishing [#cdn-publishing]
By default, the CLI does not publish translated files to the GT CDN. If you have enabled the CDN in your project settings, you can control publishing globally, per-file, or per-command.
### Global publish flag
Set `publish` at the top level to publish **all** translated files to the CDN:
```json title="gt.config.json"
{
"publish": true
}
```
You can also pass `--publish` to the `translate`, `upload`, or `save-local` commands:
```bash
npx gt translate --publish
```
### GT JSON publish flag
To publish only GT's internal translation format, use the `publish` key under `files.gt`:
```json title="gt.config.json"
{
"files": {
"gt": {
"output": "public/i18n/[locale].json",
"publish": true
}
}
}
```
### Per-file publish control
For other file types (`json`, `yaml`, `mdx`, `md`, `po`, `xliff`, `csv`, `properties`), you can control publishing per-file by using an object in the `include` array instead of a plain glob string:
```json title="gt.config.json"
{
"files": {
"json": {
"include": [
{ "pattern": "locales/[locale]/*.json", "publish": true },
{ "pattern": "locales/[locale]/internal/**/*.json", "publish": false }
]
}
}
}
```
Each entry in `include` can be either:
- A **string** — a glob pattern (no publish preference; uses the global `publish` setting)
- An **object** with `pattern` (glob) and `publish` (boolean) — explicitly opts the matched files in or out
### Resolution order
For any given file, the CLI resolves whether to publish in this order:
1. **Explicit opt-out** — file matches an include entry with `"publish": false` → not published or removed from the CDN
2. **Explicit opt-in** — file matches an include entry with `"publish": true` → published to the CDN
3. **Global fallback** — uses the top-level `publish` setting (defaults to `false` if unset)
If no publish configuration exists at any level, the publish step is skipped entirely.
---
## Example configuration
Let's break down an example `gt.config.json` file:
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["fr", "es"],
"files": {
"gt": {
"output": "public/i18n/[locale].json"
},
"mdx": {
"include": ["content/docs/[locale]/**/*.mdx"],
"transform": "*.[locale].mdx"
},
"json": {
"include": ["resources/[locale]/**/*.json"],
"exclude": ["resources/[locale]/exclude/**/*.json"]
}
}
}
```
In this example, we are translating the following files with a single call to [`gt translate`](/docs/cli/translate):
- All MDX files in the `content/docs/en` directory.
- All JSON files in the `resources/en` directory (excluding any files in the `resources/en/exclude` directory).
- All inline `` components in your React or Next.js project.
- Your `dictionary.[json|js|ts]` file.
GT: Translations will be saved to `public/i18n/es.json` and `public/i18n/fr.json`. These files can be loaded using [`loadTranslations`](/docs/react/api/config/load-translations).
MDX: Translations will be saved to the `content/docs/fr` and `content/docs/es` directories.
The file extensions will be changed to `.fr.mdx` and `.es.mdx` respectively (from `.mdx`).
JSON: Translations will be saved to the `resources/fr` and `resources/es` directories.
---
## Next steps
Learn how to use the [init command](/docs/cli/init) to generate this configuration file.
# gt: General Translation CLI tool: Keyed Metadata
URL: https://generaltranslation.com/en-US/docs/cli/reference/keyed-metadata.mdx
---
title: Keyed Metadata
description: Per-key translation metadata for JSON and YAML files
---
## Overview
Keyed metadata lets you attach translation instructions to individual keys in your JSON and YAML files. You provide a companion `.metadata.json` or `.metadata.yaml` file that mirrors the source file's key structure, with metadata objects at the leaf level.
The CLI automatically detects companion metadata files, validates them against the source structure, and sends them to the translation engine.
---
## File structure
A companion metadata file must:
- Live in the same directory as the source file
- Follow the naming convention `{name}.metadata.{ext}` (e.g., `translations.metadata.json` for `translations.json`)
- Mirror the key structure of the source file
```
translations.json # source strings
translations.metadata.json # per-key metadata
```
The metadata file mirrors the source key structure, with metadata objects at the leaves instead of strings:
```json title="translations.json"
{
"nav": {
"home": "Home",
"bank": "Bank",
"save": "Save"
},
"alerts": {
"new_lead": "You have a new lead!"
}
}
```
```json title="translations.metadata.json"
{
"nav": {
"bank": {
"context": "Riverbank — the side of a river. NOT a financial institution."
},
"save": {
"context": "Sports term — a goalkeeper preventing a goal. NOT saving data.",
"maxChars": 12
}
},
"alerts": {
"new_lead": {
"context": "Sales/CRM context. A 'lead' is a potential customer.",
"maxChars": 30
}
}
}
```
Not every key needs metadata — `home` has no entry above and translates normally. Only provide entries for keys that need specific translation instructions.
---
## Field reference
| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `context` | `string` | No | Translation instructions for this specific string |
| `maxChars` | `number` | No | Maximum character count for the translated output |
| `sourceCode` | `Record` | No | Surrounding source code context, keyed by file path |
---
## Fields
### `context`
Type: `string`
Translation instructions applied to a specific string. Use this to disambiguate words with multiple meanings, specify domain terminology, or clarify the intended interpretation.
```json
{
"bank": {
"context": "Riverbank. The side of a river where land meets water, NOT a financial institution."
}
}
```
### `maxChars`
Type: `number`
A maximum character limit on the translated output. The engine will use shorter synonyms, abbreviations, or concise phrasing to fit within the limit. This is best-effort. If the limit is unfeasible for the source content, the full translation is returned.
```json
{
"save": {
"maxChars": 10
}
}
```
### `sourceCode`
Type: `Record`
Surrounding source code context for a string. Keyed by file path, with each entry containing:
- `before` — lines of source code above the target line
- `target` — the line containing the string being translated
- `after` — lines of source code below the target line
Multiple entries per file are supported if the same string appears in different locations.
```json
{
"new_lead": {
"sourceCode": {
"components/Dashboard.tsx": [
{
"before": "function NotificationBanner({ type }) {\n const gt = useGT();",
"target": " const msg = gt('You have a new lead!');",
"after": " return {msg} ;\n}"
}
]
}
}
}
```
### Combined example
All three fields on a single key:
```json
{
"save_button": {
"context": "Sports term. A goalkeeper's save — preventing a goal from being scored. NOT saving data.",
"maxChars": 12,
"sourceCode": {
"components/MatchStats.tsx": [
{
"before": "const stats = useMatchStats();\nconst gt = useGT();",
"target": "const label = gt('Save');",
"after": "return }>{label}: {stats.saves};"
}
]
}
}
}
```
---
## YAML
Works the same way with `.metadata.yaml` or `.metadata.yml` companions:
```yaml title="translations.metadata.yaml"
ui:
buttons:
save:
context: "Sports term. A goalkeeper's save, NOT saving data."
maxChars: 12
draft:
context: "Beer on tap, as in 'draft beer'. NOT a document version."
labels:
date:
context: "The edible fruit of the date palm. NOT a calendar date."
```
---
## Validation
The CLI validates the metadata file against the source file's structure. The process exits with an error if:
- A metadata key does not exist in the source file
- A metadata value is a primitive where the source has a nested object
- A metadata value is an array where the source has an object (or vice versa)
- The root type (array vs object) does not match the source
- The metadata file is not parsable
---
## Schema support
Keyed metadata works with JSON schemas (`include` and `composite`) and YAML schemas (`include`). The metadata is automatically transformed through the same schema pipeline as the source content, so key paths align at translation time regardless of file structure.
---
## Companion file filtering
Companion metadata files are automatically matched to the corresponding source file. They are not translated as standalone files. This only applies when the corresponding source file exists in the file list. A `.metadata.json` file without a matching source file is treated as a regular file.
---
## Re-translation behavior
Changes to the metadata file alone do not trigger re-translation if the source content has not changed. To apply updated metadata, the source content must also change.
# gt-next: General Translation Next.js SDK: Compiler
URL: https://generaltranslation.com/en-US/docs/next/concepts/compiler.mdx
---
title: Compiler
description: gt-next's Rust-based SWC plugin
---
gt-next includes a Rust-based SWC plugin that performs build-time analysis to catch common translation errors and optimize performance.
## Features
### Dynamic content detection
Detects unwrapped dynamic content in translation components:
```jsx
// ❌ Invalid - dynamic content not wrapped
Hello {userName}
// ✅ Valid - dynamic content wrapped in variable component
Hello {userName}
```
### Function call validation
Detects non-literal arguments passed to translation functions:
```jsx
const gt = useGT();
// ❌ Invalid - template literals and concatenation
gt(`Hello ${name}`)
gt("Hello " + name)
// ✅ Valid - string literals with variable substitution
gt("Hello, {name}!", { name })
```
### Compile-time hash generation
Pre-computes translation hashes for better runtime performance:
```jsx
// Input
Hello world
// Output (when enabled)
Hello world
```
## Configuration
Configure the SWC plugin in your `next.config.js`:
```javascript
import { withGTConfig } from 'gt-next/config';
export default withGTConfig(nextConfig, {
locales: ['en', 'es'],
swcPluginOptions: {
logLevel: 'silent', // Control warning output
compileTimeHash: false, // Enable hash generation
},
});
```
### Options
- **`logLevel`**: Controls warning output level
- `'silent'` - No warnings (default for production)
- `'error'` - Show as build errors
- `'warn'` - Show as warnings (default for development)
- `'info'` - Show info-level messages
- `'debug'` - Show all debug information
- **`compileTimeHash`**: Enables compile-time hash generation
- `false` - Disabled (default)
- `true` - Generate hashes at build time for better performance
## Limitations
The SWC plugin processes files individually and cannot detect violations in re-exported components:
```jsx
// File A: export { T as Translate } from 'gt-next'
// File B: import { Translate } from './A'
Hello {name} // Won't be detected
```
# gt-next: General Translation Next.js SDK: Production vs Development
URL: https://generaltranslation.com/en-US/docs/next/concepts/environments.mdx
---
title: Production vs Development
description: Differences between production and development environments
---
## Overview
`gt-next` behaves differently depending on the environment your Next.js application is running in.
It detects the environment by checking the `NODE_ENV` environment variable.
## Production behavior
### Environment variables
In production, `gt-next` will only read the `GT_PROJECT_ID` and `GT_API_KEY` environment variables.
The API Key must be a Production API Key, beginning with `gtx-api-`.
If you are using a Development API Key, `gt-next` will throw an error.
### Translation loading behavior
In production, `gt-next` will attempt to load translations from the General Translation CDN, by default.
If you have configured custom translation loading behavior, such as local translations, via the `loadTranslations` function, `gt-next` will use that instead.
Translation hot reloading is disabled since it is in production.
On-demand translation for dynamic content using the `` component or `tx` function is enabled, but only in server components.
## Development behavior
### Environment variables
`gt-next` will accept the `GT_PROJECT_ID` and `GT_API_KEY` environment variables.
The API key can either be a Production API Key, beginning with `gtx-api-`, or a Development API Key, beginning with `gtx-dev-`.
If a production API key is provided in development, `gt-next` will behave as if you are in production.
This means that translation hot reloading will be disabled, and components without translations will render the original content.
### Translation loading behavior
In development, `gt-next` will first attempt to load translations in the same way as production.
These translations are loaded into memory.
When rendering a component (that uses `useGT`, ``, or `useTranslations`) in a language different than the default, `gt-next` will do the following:
1. If it detects a valid, stored translation for the given content, it will render the translation.
2. If no translation is found, it will attempt to dynamically translate the content via the General Translation API.
3. After translating, the translation will be rendered, and stored in memory for future use.
4. If the translation times out, it will fallback and render the original content.
Our API also internally caches development translations for a short period of time, so if the same translation is requested again, it will be served from cache.
These translations are isolated at the project level, so they will not be mixed up with translations from other projects.
Additionally, the cache is unique to development sessions, so cached translations will not be used in production.
`gt-next` will detect changes to components that use `useGT`, ``, or `useTranslations` and will dynamically translate the modified content via our API.
## Production vs development API keys [#api-keys]
To help distinguish between the production and development behavior of `gt-next`, we have the concept of "Production API Keys" and "Development API Keys".
### Production API keys
Production API keys are API keys beginning with `gtx-api-`.
When a Production API key is provided, `gt-next` will behave as described in the [Production Behavior](#production-behavior) section.
This means that if you are running your Next.js application in development mode, and you provide a Production API key, `gt-next` will behave as if you are in production.
Translation hot reloading will be disabled, and components without translations will render the original content.
Other than this behavior, `gt-next` will not utilize the Production API key in any way.
The CLI tool reads the `GT_API_KEY` environment variable and only accepts Production API keys.
The CLI tool will apply billing and rate-limiting using the "production" category.
### Development API keys
Development API keys are API keys beginning with `gtx-dev-`.
When a Development API key is provided, `gt-next` will behave as described in the [Development Behavior](#development-behavior) section.
When using a Development API key, billing and rate-limiting will be applied using the "development" category.
Translations created with a Development API key will not be stored, and will not be available for use in production.
The purpose of development translations is to allow you to test your application before shipping to production.
# gt-next: General Translation Next.js SDK: Standalone i18n
URL: https://generaltranslation.com/en-US/docs/next/concepts/stand-alone.mdx
---
title: Standalone i18n
description: How to use gt-react as a standalone i18n library
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Overview
`gt-next` has feature parity with many other i18n libraries.
This means that you can use `gt-next` as a standalone i18n library, without using the General Translation platform.
To do this, don't provide any environment variables such as `GT_API_KEY` or `GT_PROJECT_ID`.
See our [migration guide](/docs/next/guides/migration) for more information on how to migrate from another i18n library to `gt-next`.
## Tradeoffs
Using `gt-next` as a standalone i18n library has some tradeoffs.
### Manual translation
You will need to manually translate your app. If you use our platform, we automatically translate your app for you.
If your project only uses [dictionaries](/docs/next/guides/dictionaries) with the `useTranslations` function,
you'll need to manually translate your dictionaries, as you would with any other i18n library.
Make sure you load your translated dictionaries with the [`loadDictionary`](/docs/next/api/config/load-dictionary) function.
---
### Manual string translation
If your project is using inline translations with the [``](/docs/next/guides/t) component
or the [`useGT`](/docs/next/guides/strings) functions,
you'll also need to manually translate your strings.
Since there are no keys with inline translations, the CLI tool has a command: [`gt generate`](/docs/cli/generate)
which will automatically generate template files for your project. You'll just need to edit the template files with your translations for each language.
Make sure you load your translated strings with the [`loadTranslations`](/docs/next/api/config/load-translations) function.
### No development translations
# gt-next: General Translation Next.js SDK: Branching Components
URL: https://generaltranslation.com/en-US/docs/next/guides/branches.mdx
---
title: Branching Components
description: How to use branching components for conditional content within translations
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Branching components enable conditional content rendering within [``](/docs/next/api/components/t) components. They handle dynamic logic like if/else statements and pluralization rules while ensuring all content variations can be properly translated.
## Available components
- [``](/docs/next/api/components/branch): Conditional content based on values or states
- [``](/docs/next/api/components/plural): Automatic pluralization using locale-specific rules
## Quickstart
Branching components work inside [``](/docs/next/api/components/t) to handle conditional logic:
```jsx
import { T, Branch, Plural, Num, Var } from 'gt-next';
function NotificationPanel({ user, messageCount }) {
return (
{user.name} is currently online
}
away={{user.name} is away
}
>
{user.name} status unknown
You have {messageCount} message}
other={You have {messageCount} messages
}
/>
);
}
```
## How branching components work
Branching components solve conditional rendering within translations by:
1. **Replacing ternary operators** and conditional logic inside [``](/docs/next/api/components/t)
2. **Providing fallback content** when conditions don't match expected values
3. **Enabling translation** of all possible content variations
4. **Following locale rules** for pluralization automatically
```jsx
// ❌ This breaks - conditional logic in
{isActive ? 'User is active' : 'User is inactive'}
// ✅ This works - conditional logic with branching
User is active}
false={User is inactive
}
/>
```
## Component guide
### Branch - Conditional content
Use [``](/docs/next/api/components/branch) for any conditional rendering based on values or states:
```jsx
// User status display
Administrator Dashboard}
user={User Dashboard
}
guest={Guest Access
}
>
Access level unknown
// Boolean conditions
Welcome back!}
false={Please log in
}
/>
// Subscription tiers
Upgrade to unlock premium features}
premium={Enjoy your premium experience
}
enterprise={Contact support for enterprise solutions
}
>
Subscription status unavailable
```
### Plural - Smart pluralization
Use [``](/docs/next/api/components/plural) for content that changes based on quantity:
```jsx
// Basic pluralization
{itemCount} item in cart}
other={{itemCount} items in cart
}
/>
// Zero handling
No new notifications}
one={{notifications} notification
}
other={{notifications} notifications
}
/>
// Complex pluralization (follows Unicode CLDR rules)
Due today}
one={Due in {days} day
}
few={Due in {days} days
}
many={Due in {days} days
}
other={Due in {days} days
}
/>
```
### Combining with variable components
Branching and variable components work together seamlessly:
```jsx
Order {order.id} is pending.
Total: {order.total}
}
shipped={
Order {order.id} shipped on {order.shippedDate}
}
delivered={
Order {order.id} was delivered successfully
}
>
Order status unknown
```
## When to use branching components
### Replace ternary operators
Convert conditional logic for use within [``](/docs/next/api/components/t):
```jsx
// ❌ Can't use ternary in
{isActive ? Active user
: Inactive user
}
// ✅ Use Branch instead
Active user}
false={Inactive user
}
/>
```
### Handle multiple conditions
Replace switch statements or multiple if/else conditions:
```jsx
// ❌ Complex conditional logic
{status === 'loading' ? Loading...
:
status === 'error' ? Error occurred
:
status === 'success' ? Success!
:
Unknown status
}
// ✅ Clean branching logic
Loading...}
error={Error occurred
}
success={Success!
}
>
Unknown status
```
### Pluralization rules
Replace manual plural handling:
```jsx
// ❌ Manual pluralization
{count === 1 ? 1 item
: {count} items
}
// ✅ Automatic pluralization
{count} item}
other={{count} items
}
/>
```
## Standalone usage
Branching components can be used outside [``](/docs/next/api/components/t) for pure logic without translation:
```jsx
// Pure conditional rendering
}
light={ }
>
// Pure pluralization
}
other={ }
/>
```
## Common issues
### Missing branch keys
Always provide fallback content for unmatched values:
```jsx
// ❌ No fallback for unexpected values
}
user={ }
// What if userRole is "moderator"?
/>
// ✅ Always include fallback
}
user={ }
>
{/* Fallback for any other value */}
```
### Incomplete plural forms
Provide necessary plural forms for your default locale:
```jsx
// ❌ Missing "other" form
1 item}
// What about 0, 2, 3, etc.?
/>
// ✅ Include required forms
No items}
one={1 item
}
other={{count} items
}
/>
```
### Complex nested logic
Although this works, we recommend keeping branching logic simple and avoid deep nesting:
```jsx
// ❌ Complex nested branching
{/* Hard to read and maintain */}
// ✅ Flatten logic or use multiple components
}
active-offline={ }
inactive-online={ }
>
```
Learn more about pluralization rules in the [Unicode CLDR documentation](https://cldr.unicode.org/index/cldr-spec/plural-rules).
## Next steps
- [String Translation Guide](/docs/next/guides/strings) - Translate plain text without JSX
- [Dynamic Content Guide](/docs/key-concepts/dynamic-content) - Handle runtime translation
- API References:
- [`` Component](/docs/next/api/components/branch)
# gt-next: General Translation Next.js SDK: Cache Components
URL: https://generaltranslation.com/en-US/docs/next/guides/cache-components.mdx
---
title: Cache Components
description: Setting up Cache Components in gt-next
---
This guide shows how to use gt-next with Next.js Cache Components to optimize internationalized applications.
---
## Setup
If you have not already, follow the [Next.js Cache Components guide](https://nextjs.org/docs/app/getting-started/cache-components) to set up cache components in your project.
### Enable cache components and configure request functions
Enable cache components in your Next.js config, and define custom `getLocale` and `getRegion` request functions that use `next/root-params` so that gt-next can resolve the locale inside cached components.
Your `[locale]` segment must be a **root parameter** — the first dynamic segment in your app directory, with no `app/layout.tsx` above it. Your root layout must live inside `app/[locale]/`.
```js title="next.config.js"
const nextConfig = {
cacheComponents: true,
};
export default withGTConfig(nextConfig, {
// Point to your custom request functions
getLocalePath: './getLocale.ts',
getRegionPath: './getRegion.ts',
});
```
Create these files in your project root. They use `next/root-params` instead of `headers()`, which means they work inside `"use cache"` boundaries:
```ts title="getLocale.ts"
import { locale } from 'next/root-params';
export default async function getLocale(): Promise {
return await locale();
}
```
```ts title="getRegion.ts"
export default async function getRegion(): Promise {
return undefined;
}
```
**Do not use `headers()` in your `getLocale` or `getRegion` functions.** Calling `headers()` inside a `"use cache"` boundary causes a build error. Use `next/root-params` as shown above.
`experimentalLocaleResolution` is deprecated as of gt-next@6.16.29. It relies on unsupported Next.js internals and may break in future Next.js releases. Use explicit `getLocalePath` and `getRegionPath` configuration instead.
### Enable middleware
See the full middleware guide [here](/docs/next/guides/middleware).
```ts
import { createNextMiddleware } from 'gt-next/middleware';
export default createNextMiddleware();
export const config = {
// Match all paths except API routes, static files, and Next.js internals
matcher: ['/((?!api|static|.*\\..*|_next).*)']
};
````
### Add the `locale` parameter to cached components with translatable content
When using cached components with translatable content, you must pass the `locale` as a parameter. This ensures each locale gets its own cache entry.
```tsx
import { getLocale } from "gt-next/server"
async function CachedContent({locale}: {locale: string}) {
"use cache"
return Hello World
}
export default async function Page() {
const locale = await getLocale()
return
}
````
## Configuration notes
- When using custom `getLocalePath` and `getRegionPath`, those functions handle locale and region resolution for cached components.
- The `next/root-params` API allows reading route parameters like `[locale]` from anywhere in the component tree, including inside `"use cache"` boundaries. The root param value automatically becomes part of the cache key.
- The `[locale]` segment must be a root parameter (no `app/layout.tsx` above it).
---
## Next steps
- Read the release notes for this feature, [gt-next@6.10.0](/devlog/gt-next_v6_10_0), for more information.
# gt-next: General Translation Next.js SDK: Dictionaries
URL: https://generaltranslation.com/en-US/docs/next/guides/dictionaries.mdx
---
title: Dictionaries
description: How to use traditional dictionary-based translation patterns
---
Dictionaries provide a traditional approach to organizing translations in nested objects with key-value pairs. While [`` components](/docs/next/guides/t) are the recommended approach, dictionaries can be useful for migration from other i18n libraries or when you prefer centralized translation storage.
**Recommendation:** Use [`` components](/docs/next/guides/t) for new projects. Dictionaries are supported primarily for migration and compatibility with existing translation workflows.
## Dictionary vs component translation
### Dictionary pattern
```tsx
// dictionary.ts
export default {
greetings: {
hello: 'Hello, world!',
welcome: 'Welcome, {name}!'
}
};
// Component usage
function MyComponent() {
const t = useTranslations();
return {t('greetings.hello')}
;
}
```
### Component pattern
```tsx
// Direct component usage - recommended
function MyComponent() {
return Hello, world!
;
}
```
## Trade-offs
### Dictionary advantages
- **Centralized storage** - All translations in one place
- **Industry standard** - Familiar pattern from other i18n libraries
- **Migration friendly** - Easy to port existing translations
### Dictionary disadvantages
- **Complexity** - More setup and configuration required
- **Maintainability** - Content separated from usage makes updates harder
- **Debuggability** - Harder to trace translations back to components
- **Readability** - Keys don't show actual content
## Quickstart
### Step 1: Create dictionary
Create a dictionary file in your project root or `src` directory:
```ts title="dictionary.ts"
const dictionary = {
greetings: {
hello: 'Hello, world!',
welcome: 'Welcome to our app!'
},
navigation: {
home: 'Home',
about: 'About',
contact: 'Contact'
}
};
export default dictionary;
```
Or use JSON format:
```json title="dictionary.json"
{
"greetings": {
"hello": "Hello, world!",
"welcome": "Welcome to our app!"
},
"navigation": {
"home": "Home",
"about": "About",
"contact": "Contact"
}
}
```
The [`withGTConfig`](/docs/next/api/config/with-gt-config) function will automatically pick up the dictionary file in your project root or `src` directory.
### Step 2: Use in components
The [`useTranslations`](/docs/next/api/dictionary/use-translations) hook lets you access dictionary entries:
#### Client components
```tsx
import { useTranslations } from 'gt-next';
function MyComponent() {
const t = useTranslations();
return (
{t('greetings.hello')}
{t('greetings.welcome')}
);
}
```
#### Server components
```tsx
import { getTranslations } from 'gt-next/server';
async function MyServerComponent() {
const d = await getTranslations();
return (
{t('greetings.hello')}
{t('greetings.welcome')}
);
}
```
## Using variables
Add variables to dictionary entries using `{variable}` syntax:
```ts title="dictionary.ts"
const dictionary = {
user: {
greeting: 'Hello, {name}!',
itemCount: 'You have {count} items',
orderTotal: 'Total: ${amount}'
}
};
```
```tsx
function UserDashboard() {
const t = useTranslations();
return (
{t('user.greeting', { name: 'Alice' })}
{t('user.itemCount', { count: 5 })}
{t('user.orderTotal', { amount: 99.99 })}
);
}
```
## Using prefixes
Scope dictionary access to specific sections using prefixes:
```ts title="dictionary.ts"
const dictionary = {
dashboard: {
header: {
welcome: 'Welcome back!',
lastLogin: 'Last login: {date}'
},
stats: {
totalUsers: 'Total Users: {count}',
activeUsers: 'Active Users: {count}'
}
}
};
```
```tsx
function DashboardHeader() {
// Prefix limits access to 'dashboard.header'
const t = useTranslations('dashboard.header');
return (
);
}
function DashboardStats() {
// Different prefix for stats section
const t = useTranslations('dashboard.stats');
return (
{t('totalUsers', { count: 1000 })}
{/* -> dashboard.stats.totalUsers */}
{t('activeUsers', { count: 150 })}
{/* -> dashboard.stats.activeUsers */}
);
}
```
## Multiple language support
### Automatic translation (recommended)
Most users should use [`loadTranslations`](/docs/next/api/config/load-translations) to automatically generate translations from your base dictionary:
```ts title="dictionary.ts"
const dictionary = {
common: {
save: 'Save',
cancel: 'Cancel',
delete: 'Delete'
},
forms: {
required: 'This field is required',
email: 'Please enter a valid email'
}
};
export default dictionary;
```
Create a `loadTranslations` function to load generated translation files:
```js title="src/loadTranslations.ts"
export default async function loadTranslations(locale) {
const translations = await import(`../public/locales/${locale}.json`);
return translations.default;
}
```
[`withGTConfig`](/docs/next/api/config/with-gt-config) automatically picks up the `loadTranslations.[js|ts]` file from your `src/` directory or project root.
GT automatically generates translations for other languages based on your base dictionary. Run `npx gt translate` to generate translations for all configured languages.
### Manual translation files (migration)
For migration from other i18n libraries or manual translation management, use [`loadDictionary`](/docs/next/api/config/load-dictionary):
```ts title="src/loadDictionary.ts"
export default async function loadDictionary(locale: string) {
const translations = await import(`../public/locales/${locale}.json`);
return translations.default;
}
```
This loads JSON translation files from your `public/locales/` directory:
**Choose the right approach:** Use [`loadTranslations`](/docs/next/api/config/load-translations) for new projects with automatic translation generation, or [`loadDictionary`](/docs/next/api/config/load-dictionary) when migrating existing translation files.
## Production setup
### Build process
Add translation to your build pipeline:
```json title="package.json"
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
### Development vs production behavior
- **Development**: Dictionary entries translated on-demand with dev API key
- **Production**: All dictionary translations pre-built during build step
## Combining with components
Dictionaries and [`` components](/docs/next/guides/t) can work together:
```tsx
function MixedApproach() {
const t = useTranslations();
return (
{/* Dictionary for simple strings */}
{t('page.title')}
{/* T component for complex JSX */}
This is a complex message with links .
{/* Dictionary for form labels */}
{t('forms.email')}
);
}
```
## Next steps
**See it in action:** Check out the [dictionary pattern example app](https://github.com/gt-examples/dictionary-pattern) for a working demo — [live preview](https://dictionary-pattern.generaltranslation.dev).
- [Languages Guide](/docs/next/guides/languages) - Configure supported languages and locale settings
- [Dynamic Content Guide](/docs/next/guides/dynamic-content) - Handle runtime translation needs
- API References:
- [`useTranslations` Hook](/docs/next/api/dictionary/use-translations)
- [`getTranslations` Function](/docs/next/api/dictionary/get-translations)
# gt-next: General Translation Next.js SDK: Dynamic Content
URL: https://generaltranslation.com/en-US/docs/next/guides/dynamic-content.mdx
---
title: Dynamic Content
description: How to translate runtime content using server-side translation APIs
---
Dynamic content translation handles text that isn't available at build time - user-generated content, API responses, or database records. Use [``](/docs/next/api/components/tx) for JSX content and [`tx`](/docs/next/api/strings/tx) for plain strings, both server-side only for security.
**Use sparingly:** Dynamic translation consumes API quota and adds latency. Prefer [`` components](/docs/next/guides/t) with [variable components](/docs/next/guides/variables) whenever possible.
## When to use dynamic translation
Dynamic translation is for content that truly cannot be known at build time:
### Appropriate use cases
- **User-generated content**: Chat messages, reviews, social posts
- **External API responses**: Third-party data, RSS feeds, external services
- **Database records**: Dynamic CMS content, user profiles from APIs
- **Real-time data**: Live notifications, status messages
### Avoid for these cases
- User names, account numbers → Use [``](/docs/next/api/components/var)
- Conditional messages → Use [branch components](/docs/next/guides/branches)
- Form validation → Use [string translation](/docs/next/guides/strings)
- Static configuration → Use [shared strings](/docs/next/guides/shared-strings)
## Quickstart
### JSX content with Tx
```jsx
import { Tx } from 'gt-next';
async function UserPost({ postContent }) {
return (
{postContent}
);
}
```
### Plain strings with tx
```jsx
import { tx } from 'gt-next/server';
async function NotificationBanner({ message }) {
const translatedMessage = await tx(message);
return (
{translatedMessage}
);
}
```
## Server-side only
Both [``](/docs/next/api/components/tx) and [`tx`](/docs/next/api/strings/tx) are server-side only for security:
```jsx
// ✅ Server component
async function ServerComponent() {
const translated = await tx(dynamicContent);
return {translated}
;
}
// ❌ Client component - won't work
'use client';
function ClientComponent() {
const translated = await tx(dynamicContent); // Error!
return {translated}
;
}
```
## Examples
### User-generated content
```jsx
import { Tx } from 'gt-next';
async function ChatMessage({ message }) {
return (
{message.author}
{message.content}
);
}
```
### External API data
```jsx
import { tx } from 'gt-next/server';
async function NewsArticle({ article }) {
const translatedTitle = await tx(article.title);
return (
{translatedTitle}
{article.publishedAt}
);
}
```
### Mixed content
```jsx
import { T, Tx, Var } from 'gt-next';
async function ProductReview({ review }) {
return (
{/* Static content with variables */}
{review.author} rated this {review.rating} stars
{/* Dynamic user content */}
{review.content}
);
}
```
## API route usage
[`tx`](/docs/next/api/strings/tx) works in Next.js API route handlers, not just server components:
```tsx
// app/api/translate/route.ts
import { tx } from 'gt-next/server';
import { NextRequest, NextResponse } from 'next/server';
export async function POST(request: NextRequest) {
const { text, locale } = await request.json();
const translated = await tx(text, { locale });
return NextResponse.json({ translated });
}
```
This is useful when you need to expose translation as an API endpoint — for example, to serve client components or external services.
## Client-side translation pattern
Since [`tx`](/docs/next/api/strings/tx) is server-only, client components can translate dynamic content by calling an API route as a proxy:
```tsx
'use client';
async function translateText(text: string) {
const res = await fetch('/api/translate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ text, locale: 'fr' }),
});
const { translated } = await res.json();
return translated;
}
```
This pairs with the [API route above](#api-route-usage) to give client components access to dynamic translation.
## Translating multiple items
Use `Promise.all` to translate arrays of content in parallel:
```tsx
import { tx } from 'gt-next/server';
const translatedPosts = await Promise.all(
posts.map(async (post) => ({
...post,
title: await tx(post.title),
}))
);
```
This is useful for translating lists of database records, API responses, or any collection of dynamic strings.
## Common issues
### Avoid overuse
Don't use dynamic translation for content that can use standard components:
```jsx
// ❌ Unnecessary
const content = `Hello, ${userName}!`;
return {content} ;
// ✅ Use variable components instead
return (
Hello, {userName} !
);
```
### API quota impact
Dynamic translation consumes API quota on every request. Use caching and error handling in production applications.
## Next steps
**See it in action:** Check out the [dynamic content example app](https://github.com/gt-examples/dynamic-content-tx) for a working demo of `tx()` and `` — [live preview](https://dynamic-content-tx.generaltranslation.dev).
- [Local Translation Guide](/docs/next/guides/local-tx) - Handle translations without API calls
- [Middleware Guide](/docs/next/guides/middleware) - Language detection and routing
- API References:
- [`` Component](/docs/next/api/components/tx)
# gt-next: General Translation Next.js SDK: Changing Languages
URL: https://generaltranslation.com/en-US/docs/next/guides/languages.mdx
---
title: Changing Languages
description: How to configure and switch between languages in your Next.js app
---
Language switching allows users to change their preferred locale for your application's content. GT Next provides several approaches from simple programmatic switching to full URL-based routing with middleware.
## Available methods
- **Programmatic**: [`useSetLocale`](/docs/next/api/helpers/use-set-locale) hook for custom controls
- **Pre-built UI**: [``](/docs/next/api/components/locale-selector) component with dropdown
- **Custom UI**: [`useLocaleSelector`](/docs/next/api/helpers/use-locale-selector) hook for building custom selectors
- **URL-based**: [Middleware routing](/docs/next/guides/middleware) for locale in URL paths
## Using the `useSetLocale` hook
The [`useSetLocale`](/docs/next/api/helpers/use-set-locale) hook is a client-side hook that allows you to change the language of your app:
```tsx
import { useSetLocale } from 'gt-next/client';
export default function MyComponent() {
const setLocale = useSetLocale();
return setLocale('en')}>Set Locale ;
}
```
Simply provide the locale you want to change to as the argument to the function returned by the hook.
## Using the `` component
The [``](/docs/next/api/components/locale-selector) component provides a ready-to-use dropdown that automatically shows all configured locales:
```tsx
import { LocaleSelector } from 'gt-next/client';
export default function MyComponent() {
return ;
}
```
This component automatically:
- Shows all configured locales for your project
- Displays locales in their native language names
- Handles the switching logic
- Maintains current selection state
## Using the `useLocaleSelector` hook
If you want to build your own custom locale selector component, use [`useLocaleSelector`](/docs/next/api/helpers/use-locale-selector):
```tsx
import { useLocaleSelector } from 'gt-next/client';
function CustomLocaleSelector() {
const {
locale, // Current active locale (e.g., 'en', 'es')
locales, // Array of locales your project supports ['en', 'es', 'fr']
setLocale, // Function to change the locale: setLocale('es')
getLocaleProperties // Function to get display info for a locale
} = useLocaleSelector();
if (!locales?.length) return null;
return (
setLocale(e.target.value)}
>
{locales.map((loc) => {
const props = getLocaleProperties(loc);
return (
{props.nativeNameWithRegionCode} {/* e.g., "English (US)", "Español (ES)" */}
);
})}
);
}
```
## URL-based language switching
For SEO and better UX, you can include locale in your URLs using middleware routing. You can find more information about this approach in the [Middleware Guide](/docs/next/guides/middleware):
```
/en/products → English products page
/es/products → Spanish products page
/fr/products → French products page
```
This approach provides SEO benefits, direct links to language versions, and shareable localized links.
## Important notes
### Client components only
All language switching hooks and components must be used in client components marked with `'use client'`:
```tsx
'use client';
import { useSetLocale } from 'gt-next/client';
function LanguageSwitcher() {
const setLocale = useSetLocale();
// ... component logic
}
```
### GTProvider requirement
Language switching components must be used within a [``](/docs/next/api/components/gtprovider):
```tsx
// ✅ Correct
// ❌ Wrong - outside provider
```
## Next steps
- [Middleware Guide](/docs/next/guides/middleware) - URL-based language routing
- [Dynamic Content Guide](/docs/next/guides/dynamic-content) - Runtime content translation
- API References:
- [`useSetLocale` Hook](/docs/next/api/helpers/use-set-locale)
- [`` Component](/docs/next/api/components/locale-selector)
# gt-next: General Translation Next.js SDK: Local Translation Storage
URL: https://generaltranslation.com/en-US/docs/next/guides/local-tx.mdx
---
title: Local Translation Storage
description: Store translations in your app bundle instead of using a CDN
---
## What are local translations?
Local translations are stored in your app's bundle, as opposed to being fetched from a CDN (Content Distribution Network). When you add the `gt translate` command to your build process, this generates translations in JSON format. The final step is getting these translations into your app where they can be used.
There are two ways to do this:
1. **In your app's bundle** (local): Save translations to your app's bundle after generation
2. **In a CDN** (default): Fetch translations from a CDN at runtime
By default, `gt-next` fetches translations from the General Translation CDN. When translating your app using our API, translations are automatically saved to our CDN.
**Default behavior:** GT uses CDN storage by default. Only switch to local storage if you need the specific benefits it provides.
## Trade-offs
### Benefits of local translations
- **Faster load times**: Local translations are served directly from your app, loading faster than translations served from a CDN
- **No reliance on external services**: Your app's ability to load translations isn't dependent on CDN uptime. If translations aren't found for a locale, the app automatically falls back to the default language
- **Works offline**: Translations are bundled with your app
### Drawbacks of local translations
- **Increased bundle size**: Local translations increase your app's bundle size, potentially making the app slower to load initially
- **Content management**: To edit a translation, you must redeploy your app with the new translation every time you make changes
## Setup
### Step 1: Create load function
Add a `loadTranslations.[js|ts]` file under `./src` with the following content:
```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
const translations = await import(`../public/_gt/${locale}.json`);
return translations.default;
}
```
[`withGTConfig`](/docs/next/api/config/with-gt-config) automatically picks up the `loadTranslations.[js|ts]` file from your `src/` directory or project root.
### Step 2: Configure CLI
Run the configuration command and select local storage:
```bash
npx gt configure
```
When prompted:
- **Save to CDN?** Select "No"
- **Translation directory:** Enter `./public/_gt`
Alternatively, you can manually configure the `gt.config.json` file to use local translations. See the [CLI Configuration docs](/docs/cli/reference/config) for more information.
### Step 3: Generate translations
Now when you run the translate command, translations will be automatically downloaded and included in your codebase:
```bash
npx gt translate
```
Translations will be stored in `public/_gt/` and bundled with your app.
## Build integration
### Next.js build process
Add translation generation to your build script:
```json
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
### CI/CD pipeline
```yaml
# .github/workflows/deploy.yml
- name: Generate Translations
run: npx gt translate
- name: Build Application
run: npm run build
```
## Common issues
### Missing translation files
Ensure translations are generated before building:
```bash
# ❌ Build without translations
<...YOUR_BUILD_COMMAND...>
# ✅ Generate translations first
npx gt translate && <...YOUR_BUILD_COMMAND...>
```
### Import path errors
Match your directory structure in the load function:
```ts
// ❌ Wrong path
const t = await import(`../translations/${locale}.json`);
// ✅ Correct path for public/_gt
const t = await import(`../public/_gt/${locale}.json`);
```
### Large bundle size
Consider code splitting for apps with many languages:
```ts
// Load translations only when needed
export default async function loadTranslations(locale: string) {
// Only load if locale is active
if (locale === getCurrentLocale()) {
const translations = await import(`../public/_gt/${locale}.json`);
return translations.default;
}
return {};
}
```
Local storage works best for apps with stable translations that don't need frequent updates.
## Next steps
- [Middleware Guide](/docs/next/guides/middleware) - Language detection and routing
- [Languages Guide](/docs/next/guides/languages) - Configure supported languages
- API References:
# gt-next: General Translation Next.js SDK: Locale Aliases and SEO
URL: https://generaltranslation.com/en-US/docs/next/guides/locale-aliases.mdx
---
title: Locale Aliases and SEO
description: Use custom locale aliases for URL routing while maintaining BCP 47 compliance for search engines
---
Locale aliases let you use custom locale codes in your URLs (e.g. `/cn/` instead of `/zh/`) while keeping your SEO metadata compliant with the [BCP 47 standard](https://www.w3.org/International/articles/language-tags/) that search engines expect.
## Why aliases?
BCP 47 locale codes like `zh` (Chinese) or `zh-Hant` (Traditional Chinese) are the standard for identifying languages on the web.
However, you might want different codes in your URL paths for branding, readability, or regional reasons — for example, using `/cn/` instead of `/zh/` for your Chinese audience.
GT supports this through **custom mapping** in your `gt.config.json`. The alias is used for routing and URL paths, while the canonical BCP 47 code is used wherever search engines need it.
**SEO requirement:** Search engines only recognize [BCP 47 locale codes](https://www.w3.org/International/articles/language-tags/).
Using non-standard codes like `cn` in `hreflang` attributes or `` will cause search engines to ignore your locale signals.
## Setup
### Step 1: Configure custom mapping
Add a `customMapping` entry to your `gt.config.json` for each alias:
```json title="gt.config.json"
{
"defaultLocale": "en-US",
"locales": ["en-US", "cn", "ja", "zh-Hant"],
"customMapping": {
"cn": {
"code": "zh",
"name": "Mandarin"
}
}
}
```
Here, `cn` is the alias used in URLs and middleware routing, and `zh` is the canonical BCP 47 code.
### Step 2: Use middleware as normal
The [middleware](/docs/next/guides/middleware) and `[locale]` dynamic route work with your alias codes out of the box. Users visiting `/cn/about` will be served Chinese content — no special handling needed for routing.
## BCP 47 compliance for SEO
While aliases work seamlessly for routing, there are three places where you **must** use the canonical BCP 47 code instead of the alias:
1. The `lang` attribute on your `` tag
2. Alternate link tags in your page metadata
3. Alternate entries in your sitemap
GT provides the `resolveCanonicalLocale()` method to convert aliases back to their BCP 47 codes. You can access it via `getGTClass` from `gt-next/server`:
```ts
import { getGTClass } from 'gt-next/server';
const gtInstance = getGTClass();
const canonicalLocale = gtInstance.resolveCanonicalLocale('cn');
// Returns: "zh"
```
For non-aliased locales, `resolveCanonicalLocale()` returns the input unchanged:
```ts
gtInstance.resolveCanonicalLocale('ja'); // "ja"
gtInstance.resolveCanonicalLocale('en-US'); // "en-US"
```
### 1. HTML `lang` attribute
The `` attribute tells browsers and search engines what language the page is in. It must be a valid BCP 47 code.
In your root layout, resolve the locale before passing it to the `` tag:
```tsx title="app/[locale]/layout.tsx"
import { getGTClass } from 'gt-next/server';
export default function RootLayout({
children,
params,
}: {
children: React.ReactNode;
params: { locale: string };
}) {
const gtInstance = getGTClass();
const canonicalLocale = gtInstance.resolveCanonicalLocale(params.locale);
return (
{children}
);
}
```
Without this, a page at `/cn/about` would incorrectly render ``, which search engines don't recognize.
### 2. Metadata alternates
Alternate links tell search engines which versions of a page exist in other languages. The `hreflang` attribute must use BCP 47 codes.
```tsx title="app/[locale]/layout.tsx"
import type { Metadata } from 'next';
import { getGTClass } from 'gt-next/server';
export async function generateMetadata({
params,
}: {
params: { locale: string };
}): Promise {
const gtInstance = getGTClass();
const locales = ['en-US', 'cn', 'ja', 'zh-Hant'];
// Build alternates with canonical BCP 47 codes as keys
const languages: Record = {};
for (const locale of locales) {
const canonical = gtInstance.resolveCanonicalLocale(locale);
languages[canonical] = `https://example.com/${locale}`;
}
// Add x-default for the default locale
languages['x-default'] = 'https://example.com';
return {
alternates: {
canonical: `https://example.com/${params.locale}`,
languages,
},
};
}
```
This produces correct ` ` tags in the page head:
```html
```
Notice that the `hreflang` values use canonical codes (`zh`, not `cn`), while the `href` URLs still use the alias paths (`/cn/`).
### 3. Sitemap alternates
If you use a [dynamic sitemap](https://nextjs.org/docs/app/api-reference/file-conventions/metadata/sitemap), apply the same pattern:
```ts title="app/sitemap.ts"
import type { MetadataRoute } from 'next';
import { getGTClass } from 'gt-next/server';
export default function sitemap(): MetadataRoute.Sitemap {
const gtInstance = getGTClass();
const locales = ['en-US', 'cn', 'ja', 'zh-Hant'];
const baseUrl = 'https://example.com';
const pages = ['', '/about', '/pricing'];
return pages.map((page) => {
// Build language alternates with canonical codes
const languages: Record = {};
for (const locale of locales) {
const canonical = gtInstance.resolveCanonicalLocale(locale);
languages[canonical] = `${baseUrl}/${locale}${page}`;
}
return {
url: `${baseUrl}${page}`,
lastModified: new Date(),
alternates: {
languages,
},
};
});
}
```
This generates sitemap XML with proper `hreflang` attributes:
```xml
https://example.com
```
## Common mistakes
| Mistake | Impact | Fix |
|---|---|---|
| Using alias code in `` | Search engines can't identify the page language | Use `resolveCanonicalLocale()` for the `lang` attribute |
| Using alias code in `hreflang` | Search engines ignore the alternate link | Use `resolveCanonicalLocale()` for `hreflang` values |
| Missing `x-default` alternate | No fallback for users whose language isn't listed | Add `x-default` pointing to your default locale URL |
| Inconsistent alternates between HTML and sitemap | Conflicting signals confuse crawlers | Use `resolveCanonicalLocale()` in both places |
## Next steps
- Learn about [middleware](/docs/next/guides/middleware) for locale-based URL routing
- See [`resolveCanonicalLocale`](/docs/core/class/methods/locales/resolve-canonical-locale) API reference
- Configure [`customMapping`](/docs/cli/reference/config) in your `gt.config.json`
# gt-next: General Translation Next.js SDK: Middleware
URL: https://generaltranslation.com/en-US/docs/next/guides/middleware.mdx
---
title: Middleware
description: Automatic language detection and URL routing based on user preferences
---
Middleware automatically detects user language preferences and redirects them to the appropriate localized version of your site.
It uses browser settings, geolocation, and user preferences to serve the right language before any content loads.
**File location:** Place `proxy.ts` in your project root, at the same level as your `app/` directory - not inside it. `proxy.ts` (Next.js 16+) or `middleware.ts` (Next.js 15 and below)
## Setup
### Step 1: Create dynamic route
Create a `[locale]` directory in your `app/` folder and move all pages inside it:
### Step 2: Add middleware
Create `proxy.ts` in your project root:
```ts
import { createNextMiddleware } from 'gt-next/middleware';
export default createNextMiddleware();
export const config = {
// Match all paths except API routes, static files, and Next.js internals
matcher: ['/((?!api|static|.*\\..*|_next).*)']
};
```
This enables automatic language detection and URL routing with locale prefixes like `/en/about`, `/es/about`.
## Language detection
The middleware detects user language preferences in this order:
1. **URL locale** - `/es/about` → Spanish
2. **User cookie** - Previous language selection
3. **Browser headers** - `Accept-Language` header
4. **Default locale** - Configured fallback language
The middleware automatically handles browser language detection and cookie persistence without additional configuration.
## Localized paths
Customize URL paths for different languages:
```ts
export default createNextMiddleware({
pathConfig: {
// English: /en/products, Chinese: /zh/产品
"/products": {
"zh": "/产品"
},
// Dynamic routes: /en/product/123, /zh/产品/123
"/product/[id]": {
"zh": "/产品/[id]"
}
}
});
```
## URL structure
By default, your default locale will **not** be prefixed with a locale code:
```
/about → /about (default locale: English)
/about → /es/about (Spanish)
/about → /fr/about (French)
```
### Add prefix to default locale
To prefix all locales including the default:
```ts
export default createNextMiddleware({
prefixDefaultLocale: true
});
```
Result:
```
/about → /en/about (English, with prefix)
/about → /es/about (Spanish, with prefix)
/about → /fr/about (French, with prefix)
```
## Common issues
### Missing dynamic route
All pages must be inside `[locale]/`:
```
❌ Wrong:
app/
├── page.tsx
└── about/page.tsx
✅ Correct:
app/
└── [locale]/
├── page.tsx
└── about/page.tsx
```
### Matcher configuration
Exclude API routes and static files:
```ts
export const config = {
matcher: ['/((?!api|static|.*\\..*|_next).*)']
};
```
Test your middleware configuration thoroughly - incorrect matchers can cause infinite redirects or break static assets.
## Next steps
**See it in action:** The [static site generation example app](https://github.com/gt-examples/static-site-generation) includes a full middleware setup with locale routing — [live preview](https://static-site-generation.generaltranslation.dev).
- [SSG Guide](/docs/next/guides/ssg) - Static generation with locale routing
- [RTL Support](/docs/next/guides/rtl) - Right-to-left languages
- API References: [`createNextMiddleware()`](/docs/next/api/middleware/create-next-middleware)
# gt-next: General Translation Next.js SDK: Migrating
URL: https://generaltranslation.com/en-US/docs/next/guides/migration.mdx
---
title: Migrating
description: Learn how to migrate a project to gt-next
---
## Overview
This guide will cover the steps needed to migrate a project that's already using an i18n library to gt-next.
We'll also provide some tips and suggestions for how to make the migration as smooth as possible.
## Prerequisites
- A project that is currently using another i18n library.
- A basic understanding of the `gt-next` library.
## Why migrate?
There are many reasons why you might want to migrate your project to gt-next.
Here are just a few:
- **No more JSON files:** Never manage translations in JSON files again.
All of your content lives inline with your code, where it belongs.
- **Automatic translations:** Generate high quality, context-aware translations with our CLI tool.
You'll never have to wait for translations again.
- **Experiment in dev:** Easily experiment with translations in development with translation hot-reloading.
## Setup
Install `gt-next` and the `gt` CLI tool.
```bash
npm i gt-next gt
```
```bash
yarn add gt-next
yarn add --dev gt
```
```bash
bun add gt-next
bun add --dev gt
```
```bash
pnpm add gt-next
pnpm add --save-dev gt
```
Create a `gt.config.json` file in the root of your project containing a `defaultLocale` property and a `locales` array.
```json title="gt.config.json" copy
{
"defaultLocale": "en",
"locales": ["en", "fr", "es"]
}
```
Then, add the `` component to the root layout of your app.
```tsx title="app/layout.tsx" copy
import { GTProvider } from 'gt-next'
export default function RootLayout({ children }) {
return (
{children}
)
}
```
Next, add `withGTConfig` to your `next.config.js` file.
```js title="next.config.ts" copy
import { withGTConfig } from 'gt-next/config'
const nextConfig = {
// Your next.config.ts options
}
export default withGTConfig(nextConfig, {
// Your GT configuration
})
```
For more detailed steps, see the [quickstart guide](/docs/next).
At this point, you have 3 options:
1. Fully migrate your entire project to `gt-next`, and remove the old i18n library.
2. Fully migrate your project, but keep using dictionaries from the old i18n library.
2. Keep using the old i18n library for now, and only migrate part of your project to `gt-next`.
For more details on each option, see the [migration strategies](#strategies) section.
## Migration strategies [#strategies]
### Option 1: Fully migrate your entire project
This option is the most straightforward, and will also require the most code changes in one go.
After you've set up your project, you'll need to search for all instances of your old i18n library and replace them with `gt-next`.
If your app is using React hooks such as `useTranslations`, search for all instances of `useTranslations` in your codebase and replace them with `useGT`.
Then, you'll need to replace all the string keys with their actual string values.
For example, if your old code looks like this:
```json title="dictionary.json"
{
"hello": {
"description": "Hello, world!"
}
}
```
```tsx
export default function MyComponent() {
const { t } = useTranslation()
return {t('hello.description')}
}
```
You'll need to replace it with:
```tsx
export default function MyComponent() {
const gt = useGT()
return {gt('Hello, world!')}
}
// OR
export default function MyComponent() {
return Hello, world!
}
```
Do this for all instances of your old i18n library.
### Option 2: Fully migrate your project, but keep using dictionaries from the old i18n library
Let's say that you want to migrate your project to `gt-next`, but you want to keep using dictionaries from the old i18n library
and only use GT inline features for new content.
In this case, you can do something similar to Option 1:
Find all instances of your old i18n library, such as `useTranslations` hooks, and replace them with `useTranslations` hooks from `gt-next`.
The `useTranslations` hook behaves very similarly to `useTranslations` hooks in other i18n libraries, and you can use it in the same way.
```tsx
import { useTranslation } from 'react-i18next'
export default function MyComponent() {
const { t } = useTranslation()
return {t('hello.description')}
}
```
```tsx
import { useTranslations } from 'gt-next'
export default function MyComponent() {
const t = useTranslations()
return {t('hello.description')}
}
```
In terms of configuration, you'll need to create a `dictionary.[js|ts|json]` file in your project root or `src` directory.
Copy the contents of your old dictionary file into this new file.
The initialization `withGTConfig` function in `next.config.js` will automatically pick up the dictionary file in your project root or `src` directory.
See the [dictionaries](/docs/next/guides/dictionaries) guide for more details.
### Option 3: Keep using the old i18n library for now, and only migrate part of your project to `gt-next`
This option is the most flexible, and will require the least code changes in one go.
In this case, you can do something similar to Option 2, but only migrate part of your project to `gt-next`.
For example, you can keep using the old i18n library for some components, and only use `gt-next` for others and for new content.
This option is not recommended, as you will have to manage two different i18n libraries in your project, which may be complex and lead to bugs.
## Migration tips
### 1. Use the `useGT` hook or `` component as much as possible
Wherever possible, we recommend using the `useGT` hook or `` component.
This will make editing your content much easier in the future, and make your codebase much more readable.
### 2. Use the `useTranslations` hook for existing content
The `useTranslations` hook is a great way to keep using your existing dictionaries.
We offer it as a way to make migration easier, but we don't recommend using it for new content.
### 3. Using AI
If you are using AI to help you migrate your project, we have a `LLMs.txt` and `LLMs-full.txt` available at:
- [LLMs.txt](/llms.txt)
- [LLMs-full.txt](/llms-full.txt)
# gt-next: General Translation Next.js SDK: Right-to-Left Support
URL: https://generaltranslation.com/en-US/docs/next/guides/rtl.mdx
---
title: Right-to-Left Support
description: Configure your Next.js app for Arabic, Hebrew, and other RTL languages
---
Right-to-left (RTL) language support handles text direction and layout mirroring for languages like Arabic, Hebrew, Persian, and Urdu. GT provides automatic direction detection through the `useLocaleDirection` hook.
**RTL languages:** Over 500 million people speak RTL languages including Arabic, Hebrew, Persian, and Urdu.
## Quick setup
Use GT's built-in hooks to automatically detect and set text direction:
{/* useLocale and useLocaleDirection work in server components as long as the component is not async */}
```tsx
// app/[locale]/layout.tsx
import { useLocale, useLocaleDirection, GTProvider } from 'gt-next';
export default function RootLayout({ children }) {
const locale = useLocale(); // e.g. "ar" for Arabic
const dir = useLocaleDirection(); // e.g. "rtl" for right-to-left
return (
{children}
);
}
```
That's it! GT automatically detects RTL languages and returns the correct direction.
Compare with the [General Translation website](https://generaltranslation.com) in [English](https://generaltranslation.com/en-US/home) vs [Arabic](https://generaltranslation.com/ar/home) to see RTL in action.
# gt-next: General Translation Next.js SDK: Shared Strings
URL: https://generaltranslation.com/en-US/docs/next/guides/shared-strings.mdx
---
title: Shared Strings
description: How to internationalize strings used across multiple components and files
---
Shared strings are text values used in multiple places throughout your application - like navigation labels, form messages, or configuration data. Instead of duplicating translation logic everywhere, use [`msg`](/docs/next/api/strings/msg) to mark strings for translation and [`useMessages`](/docs/next/api/strings/use-messages) to decode them.
## The problem with shared content
Consider this navigation configuration used across your app:
```tsx
// navData.ts
export const navData = [
{
label: 'Home',
description: 'The home page',
href: '/'
},
{
label: 'About',
description: 'Information about the company',
href: '/about'
}
];
```
To internationalize this, you'd typically need to:
1. Convert it to a function that accepts a translation function
2. Update every usage to call the function with `t`
3. Manage the complexity across your codebase
This creates maintenance overhead and makes your code harder to read. The [`msg`](/docs/next/api/strings/msg) function solves this by letting you mark strings for translation in-place, then decode them when needed.
## Quickstart
Use [`msg`](/docs/next/api/strings/msg) to mark strings and [`useMessages`](/docs/next/api/strings/use-messages) to decode them:
```tsx
// navData.ts - Mark strings for translation
import { msg } from 'gt-next';
export const navData = [
{
label: msg('Home'),
description: msg('The home page'),
href: '/'
},
{
label: msg('About'),
description: msg('Information about the company'),
href: '/about'
}
];
```
```tsx
// Component usage - Decode marked strings
import { useMessages } from 'gt-next';
import { navData } from './navData';
function Navigation() {
const m = useMessages();
return (
{navData.map((item) => (
{m(item.label)}
))}
);
}
```
## How shared strings work
The shared string system works in two phases:
1. **Mark Phase**: [`msg`](/docs/next/api/strings/msg) encodes strings with translation metadata
2. **Decode Phase**: [`useMessages`](/docs/next/api/strings/use-messages) or [`getMessages`](/docs/next/api/strings/get-messages) decode and translate the strings
```tsx
// msg() encodes the string with metadata
const encoded = msg('Hello, world!');
console.log(encoded); // "Hello, world!:eyIkX2hhc2giOiJkMjA3MDliZGExNjNlZmM2In0="
// useMessages() decodes and translates
const m = useMessages();
const translated = m(encoded); // "Hello, world!" in user's language
```
Encoded strings from [`msg`](/docs/next/api/strings/msg) cannot be used directly - they must be decoded with [`useMessages`](/docs/next/api/strings/use-messages) or [`getMessages`](/docs/next/api/strings/get-messages).
## Client vs server usage
### Client components
Use [`useMessages`](/docs/next/api/strings/use-messages) hook:
```tsx
import { useMessages } from 'gt-next';
const encodedString = msg('Hello, world!');
function MyComponent() {
const m = useMessages();
return {m(encodedString)}
;
}
```
### Server components
Use [`getMessages`](/docs/next/api/strings/get-messages) function:
```tsx
import { getMessages } from 'gt-next/server';
const encodedString = msg('Hello, world!');
async function MyServerComponent() {
const m = await getMessages();
return {m(encodedString)}
;
}
```
## Getting original strings with decodeMsg
Sometimes you need to access the original string without translation, such as for logging, debugging, or comparisons. Use [`decodeMsg`](/docs/next/api/strings/msg) to extract the original text:
```tsx
import { decodeMsg } from 'gt-next';
const encoded = msg('Hello, world!');
const original = decodeMsg(encoded); // "Hello, world!" (original)
const translated = m(encoded); // "Hello, world!" (in user's language)
// Useful for logging or debugging
console.log('Original string:', decodeMsg(encoded));
console.log('Translated string:', m(encoded));
```
### Use cases for decodeMsg
- **Development & Debugging**: Log original strings for troubleshooting
- **Fallback Handling**: Use original text when translations fail
- **String Comparisons**: Compare against known original values
- **Analytics**: Track original string usage
```tsx
// Example: Fallback handling
function getDisplayText(encodedStr) {
const m = useMessages();
try {
return m(encodedStr);
} catch (error) {
console.warn('Translation failed, using original:', decodeMsg(encodedStr));
return decodeMsg(encodedStr);
}
}
```
## Using variables
For strings with dynamic content, use placeholders and pass variables:
```tsx
// Mark string with variables
const items = 100;
export const pricing = [
{
name: 'Basic',
price: 100,
description: msg('The basic plan includes {items} items', { items })
}
];
```
```tsx
// Use in component
function PricingCard() {
const m = useMessages();
return (
{pricing[0].name}
{m(pricing[0].description)}
);
}
```
### ICU message format
For advanced formatting, use ICU syntax:
```tsx
const count = 10;
const message = msg('There are {count, plural, =0 {no items} =1 {one item} other {{count} items}} in the cart', { count });
```
Learn more about ICU Message Format in the [Unicode documentation](https://unicode-org.github.io/icu/userguide/format_parse/messages/).
## Examples
### Navigation configuration
```tsx
// config/navigation.ts
import { msg } from 'gt-next';
export const mainNav = [
{
label: msg('Home'),
href: '/',
icon: 'home'
},
{
label: msg('Products'),
href: '/products',
icon: 'package'
},
{
label: msg('About Us'),
href: '/about',
icon: 'info'
}
];
export const footerLinks = [
{
title: msg('Company'),
links: [
{ label: msg('About'), href: '/about' },
{ label: msg('Careers'), href: '/careers' },
{ label: msg('Contact'), href: '/contact' }
]
},
{
title: msg('Support'),
links: [
{ label: msg('Help Center'), href: '/help' },
{ label: msg('Documentation'), href: '/docs' },
{ label: msg('API Reference'), href: '/api' }
]
}
];
```
```tsx
// components/Navigation.tsx
import { useMessages } from 'gt-next';
import { mainNav } from '../config/navigation';
function Navigation() {
const m = useMessages();
return (
{mainNav.map((item) => (
{m(item.label)}
))}
);
}
```
### Form configuration
```tsx
// config/forms.ts
import { msg } from 'gt-next';
export const formMessages = {
placeholders: {
email: msg('Enter your email address'),
password: msg('Enter your password'),
message: msg('Type your message here...')
},
actions: {
send: msg('Send Message'),
save: msg('Save Changes'),
cancel: msg('Cancel')
},
validation: {
required: msg('This field is required'),
email: msg('Please enter a valid email address'),
minLength: msg('Must be at least {min} characters', { min: 8 }),
maxLength: msg('Cannot exceed {max} characters', { max: 100 })
},
success: {
saved: msg('Changes saved successfully'),
sent: msg('Message sent successfully'),
updated: msg('Profile updated')
},
errors: {
network: msg('Network error - please try again'),
server: msg('Server error - please contact support'),
timeout: msg('Request timed out - please try again')
}
};
```
```tsx
// components/ContactForm.tsx
import { useMessages } from 'gt-next';
import { formMessages } from '../config/forms';
function ContactForm() {
const m = useMessages();
const [errors, setErrors] = useState({});
return (
);
}
```
### Dynamic content generation
```tsx
// utils/productData.ts
import { msg } from 'gt-next';
function mockProducts() {
return [
{ name: 'iPhone 15', company: 'Apple', category: 'Electronics' },
{ name: 'Galaxy S24', company: 'Samsung', category: 'Electronics' }
];
}
export function getProductData() {
const products = mockProducts();
return products.map(product => ({
...product,
description: msg('{name} is a {category} product by {company}', {
name: product.name,
category: product.category,
company: product.company
})
}));
}
```
```tsx
// components/ProductList.tsx
import { useMessages } from 'gt-next';
import { getProductData } from '../utils/productData';
function ProductList() {
const m = useMessages();
const products = getProductData();
return (
{products.map(product => (
{product.name}
{m(product.description)}
))}
);
}
```
## Common issues
### Using encoded strings directly
Never use the output of [`msg`](/docs/next/api/strings/msg) directly:
```tsx
// ❌ Wrong - encoded string used directly
const encoded = msg('Hello, world!');
return {encoded}
; // Shows encoded string, not translation
// ✅ Correct - decode the string first
const encoded = msg('Hello, world!');
const m = useMessages();
return {m(encoded)}
; // Shows proper translation
```
### Dynamic content in msg()
Strings must be known at build time:
```tsx
// ❌ Wrong - dynamic template literal
const name = 'John';
const message = msg(`Hello, ${name}`); // Build time error
// ✅ Correct - use variables
const name = 'John';
const message = msg('Hello, {name}', { name });
```
### Forgetting to decode
Every [`msg`](/docs/next/api/strings/msg) string needs to be decoded:
```tsx
// ❌ Missing decoding
const config = {
title: msg('Dashboard'),
subtitle: msg('Welcome back')
};
// Later in component - forgot to decode
return {config.title} ; // Shows encoded string
// ✅ Correct - decode when using
const m = useMessages();
return {m(config.title)} ; // Shows translated title
```
## Next steps
- [Dictionaries Guide](/docs/next/guides/dictionaries) - Organize translations with structured data
- [Languages Guide](/docs/next/guides/languages) - Configure supported languages
- API References:
- [`msg` Function](/docs/next/api/strings/msg)
- [`useMessages` Hook](/docs/next/api/strings/use-messages)
# gt-next: General Translation Next.js SDK: Static Site Generation
URL: https://generaltranslation.com/en-US/docs/next/guides/ssg.mdx
---
title: Static Site Generation
description: Pre-render internationalized pages at build time for optimal performance
---
## Overview
Static Site Generation (SSG) pre-renders pages at build time, creating static HTML files that can be served directly without server-side processing.
When combined with internationalization, SSG generates pre-rendered versions for each locale.
**Watch out for any of the following issues when setting up SSG:**
- [Next.js version compatibility](#nextjs-version-compatibility)
- [Pages not generating statically](#pages-not-generating-statically)
- [Production runtime error: "DYNAMIC_SERVER_USAGE"](#production-runtime-error-dynamic_server_usage)
- ["Export locale doesn't exist in target module"](#export-locale-doesnt-exist-in-target-module)
- [Metadata image routes (OG images) fail with `getLocale()`](#metadata-image-routes-og-images-fail-with-getlocale)
---
## Setup
### Setup requirements
To enable SSG with GT, you need:
1. **App Router with middleware routing** - see [middleware guide](/docs/next/guides/middleware)
2. **Custom `getLocale` function** - for locale detection during static rendering
3. **Disable `getRegion`** - region detection is not supported during static rendering
4. **`generateStaticParams` function** - for generating static parameters for each locale
5. **Layout files inside of the `/[locale]` directory** - all layout files (so typically `layout.tsx` and `page.tsx`) should be descendants of the `/[locale]` directory
### Step 1: Configure middleware
Set up middleware for dynamic requests (see [middleware guide](/docs/next/guides/middleware)):
```ts
// proxy.ts (Next.js 16+) or middleware.ts (Next.js 15 and below)
import { createNextMiddleware } from 'gt-next/middleware';
export default createNextMiddleware();
export const config = {
matcher: ['/((?!api|static|.*\\..*|_next).*)'],
};
```
### Step 2: Define locale and region detection
Create a `getLocale` and `getRegion` function for locale and region detection during static rendering:
#### Next.js 15.5+
```ts
// getLocale.ts
import { locale } from 'next/root-params';
export default async function getLocale() {
return await locale();
}
```
#### Next.js 15.1-15.4
```ts
// getLocale.ts
import { unstable_rootParams } from 'next/server';
export default async function getLocale() {
return (await unstable_rootParams())?.locale;
}
```
### Step 3: Disable getRegion
Since region detection is not supported during static rendering, you need to overwrite the `getRegion` function to return a fixed region.
```ts
// getRegion.ts
export default async function getRegion() {
return undefined;
}
```
### Step 4: Configure generateStaticParams
Make sure you have [`generateStaticParams`](https://nextjs.org/docs/app/api-reference/functions/generate-static-params) configured for your locales.
```tsx title="page.tsx"
import { getLocales } from 'gt-next/server';
export async function generateStaticParams() {
return getLocales().map((locale) => ({ locale }));
}
export default async function Page() {
...
}
```
### Step 5: Move any layout files inside of the `/[locale]` directory
All files need to have access to the user's locale via the `/[locale]` field in the URL.
Therefore, they must be descendants of the `/[locale]` directory.
Make sure you move your root layout file to `/[locale]/layout.tsx`.
---
## Additional configuration
If you do not want `getLocale.ts` and `getRegion.ts` in your root directory, you can specify a custom directory in your `next.config.js` file.
```js
// next.config.js
export default withGTConfig(nextConfig, {
getLocalePath: './src/i18n/getLocale.ts',
getRegionPath: './src/i18n/getRegion.ts',
});
```
## Common issues [#common-issues]
### Next.js version compatibility
For versions earlier than Next.js 15.1, there is no way to access URL path parameters during static generation. You will need to upgrade to Next.js 15.1 or later to use SSG with gt-next.
### Pages not generating statically
If your pages aren't being statically generated, ensure that:
- Your `getLocale` and `getRegion` functions are properly configured
### Production runtime error: "DYNAMIC_SERVER_USAGE"
```
⨯ [Error: An error occurred in the Server Components render. The specific message is omitted in production builds to avoid leaking sensitive details. A digest property is included on this error instance which may provide additional details about the nature of the error.] {
digest: 'DYNAMIC_SERVER_USAGE'
}
```
This error occurs when `getLocale` or `getRegion` files do not exist or are not properly configured.
Double check that [step 2](#step-2-define-locale-and-region-detection) and [step 3](#step-3-disable-getregion) are complete.
### "Export locale doesn't exist in target module"
```
./getLocale.ts:2:1
Export locale doesn't exist in target module
1 | // getLocale.ts
> 2 | import { locale } from 'next/root-params';
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
3 | export default async function getLocale() {
4 | return await locale();
5 | }
```
This error typically occurs when you have a `layout.tsx`, `page.tsx`, etc. file that is not inside of the `/[locale]` directory.
To fix this issue, make sure that all of your route segment files (so typically `layout.tsx` and `page.tsx`) are descendants of the `/[locale]` directory.
During SSG, the only way to resolve a user's locale is via the URL path.
So, if we try to execute a `layout.tsx` file outside of the `/[locale]` directory, it will error because it does not have access to this root param.
The unintuitive part about this is that when a page renders, so does every `layout.tsx` file wrapping it.
So, you could have added SSG to a `page.tsx` file that is very much inside of the `/[locale]` directory, but there is actually a `layout.tsx` file somewhere else responsible for the error.
We strongly recommend against this practice.
All route segment files (excluding `not-found.tsx`) should be located inside of the `/[locale]` directory when using SSG.
But, if you must, you will need two separate root layout files: one inside of the `/[locale]` directory and one outside of it.
This way, SSG will only execute the layout inside of the `/[locale]` directory.
Additionally, you may have to modify the middleware to route to whatever segments exist outside of the `/[locale]` directory, skipping the localization middleware.
### Metadata image routes (OG images) fail with `getLocale()`
```
Error: Route /[locale]/.../opengraph-image used
import('next/root-params').locale() inside a Route Handler.
```
Next.js metadata image routes (`opengraph-image.tsx`, `twitter-image.tsx`) are Route Handlers internally, and `next/root-params` is not supported in Route Handlers.
This means `getLocale()`, `getMessages()`, and `getGT()` will fail in these contexts.
**Fix:** Use `registerLocale()` to explicitly set the locale at the top of the handler:
```tsx title="app/[locale]/opengraph-image.tsx"
import { ImageResponse } from 'next/og';
import { registerLocale, getMessages, msg } from 'gt-next/server';
const HEADING = msg('Welcome to our site');
export default async function OGImage({
params,
}: {
params: Promise<{ locale: string }>;
}) {
const { locale } = await params;
registerLocale(locale);
const m = await getMessages();
return new ImageResponse(
(
{m(HEADING)}
),
{ width: 1200, height: 630 }
);
}
```
This also applies to `twitter-image.tsx` and any other metadata image routes.
---
## Further reading
**See it in action:** Check out the [static site generation example app](https://github.com/gt-examples/static-site-generation) for a working demo — [live preview](https://static-site-generation.generaltranslation.dev).
- Check out the [middleware guide](/docs/next/guides/middleware) required for locale routing
- Check out the [release notes](/devlog/gt-next_v6_10_0) for migrating from legacy SSG pattern
- See an example app in the monorepo [here](https://github.com/generaltranslation/gt/tree/main/examples/next-ssg)
# gt-next: General Translation Next.js SDK: Strings
URL: https://generaltranslation.com/en-US/docs/next/guides/strings.mdx
---
title: Strings
description: How to internationalize plain text strings using useGT
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
String translation provides direct access to text translations without JSX, perfect for attributes, object properties, and plain text values. Use [`useGT`](/docs/next/api/strings/use-gt) in Next.js components for string translation.
## Quickstart
```jsx
import { useGT } from 'gt-next';
function MyComponent() {
const gt = useGT();
return (
);
}
```
## When to use string translation
String translation is ideal when you need plain text rather than JSX:
### HTML attributes
```jsx
const gt = useGT();
```
### Object properties
```jsx
const gt = useGT();
const user = {
name: 'John',
role: 'admin',
bio: gt('Experienced software developer with 5 years in React'),
status: gt('Currently available for projects')
};
```
### Configuration & constants
```jsx
const gt = useGT();
const navigationItems = [
{ label: gt('Home'), href: '/' },
{ label: gt('Products'), href: '/products' },
{ label: gt('Contact'), href: '/contact' }
];
```
### When to use T instead
Use the [`` component](/docs/next/api/components/t) for JSX content:
```jsx
// ✅ Use for JSX content
Welcome to our store !
// ✅ Use string translation for plain text
```
## Using variables
### Basic variables
Replace placeholders with dynamic values:
```jsx
const gt = useGT();
const itemCount = 5;
// String with placeholder
const message = gt('You have {count} items in your cart', { count: itemCount });
// Result: "You have 5 items in your cart"
```
### Multiple variables
```jsx
const gt = useGT();
const order = { id: 'ORD-123', total: 99.99, date: '2024-01-15' };
const confirmation = gt(
'Order {orderId} for ${total} was placed on {date}',
{
orderId: order.id,
total: order.total,
date: order.date
}
);
```
### ICU message format
For advanced formatting, use ICU syntax:
```jsx
const gt = useGT();
translate('There are {count, plural, =0 {no items} =1 {one item} other {{count} items}} in the cart', { count: 10 });
```
Learn more about ICU Message Format in the [Unicode documentation](https://unicode-org.github.io/icu/userguide/format_parse/messages/).
## Examples
### Form inputs
```jsx
import { useGT } from 'gt-next';
function ContactForm() {
const gt = useGT();
return (
);
}
```
### Navigation menu
```jsx
import { useGT } from 'gt-next';
function Navigation() {
const gt = useGT();
const menuItems = [
{ label: gt('Home'), href: '/', icon: 'home' },
{ label: gt('About Us'), href: '/about', icon: 'info' },
{ label: gt('Services'), href: '/services', icon: 'briefcase' },
{ label: gt('Contact'), href: '/contact', icon: 'mail' }
];
return (
{menuItems.map((item) => (
{item.label}
))}
);
}
```
### Dynamic content factory
```jsx
// utils/productData.js
export function getProductMessages(gt) {
return {
categories: [
{ id: 'electronics', name: gt('Electronics') },
{ id: 'clothing', name: gt('Clothing') },
{ id: 'books', name: gt('Books') }
],
statusMessages: {
available: gt('In stock and ready to ship'),
backordered: gt('Currently backordered - ships in 2-3 weeks'),
discontinued: gt('This item has been discontinued')
},
errors: {
notFound: gt('Product not found'),
outOfStock: gt('Sorry, this item is currently out of stock')
}
};
}
// components/ProductCard.jsx
import { useGT } from 'gt-next';
import { getProductMessages } from '../utils/productData';
function ProductCard({ product }) {
const gt = useGT();
const messages = getProductMessages(gt);
return (
{product.name}
{messages.statusMessages[product.status]}
{messages.categories.find(c => c.id === product.categoryId)?.name}
);
}
```
### Component with document title
```jsx
import { useGT } from 'gt-next';
import { useEffect } from 'react';
function ProductPage() {
const gt = useGT();
useEffect(() => {
document.title = gt('Product Catalog - Find What You Need');
// Update meta description
const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) {
metaDescription.setAttribute('content', gt('Browse our extensive collection of high-quality products'));
}
}, [gt]);
return (
{gt('Featured Products')}
{gt('Check out our latest and most popular items')}
);
}
```
## Common issues
### Dynamic content at runtime
Strings must be known at build time - you cannot translate dynamic content:
```jsx
// ❌ Dynamic content won't work
function MyComponent() {
const [userMessage, setUserMessage] = useState('');
const gt = useGT();
return {gt(userMessage)}
; // This will fail
}
// ✅ Use predefined strings
function MyComponent() {
const [messageType, setMessageType] = useState('welcome');
const gt = useGT();
const messages = {
welcome: gt('Welcome to our app!'),
goodbye: gt('Thanks for visiting!')
};
return {messages[messageType]}
;
}
```
### Hook rules violations
Follow React hook rules when using [`useGT`](/docs/next/api/strings/use-gt):
```jsx
// ❌ Don't call hooks conditionally
function MyComponent({ showMessage }) {
if (showMessage) {
const gt = useGT(); // Hook rule violation
return {gt('Hello!')}
;
}
return null;
}
// ✅ Always call hooks at top level
function MyComponent({ showMessage }) {
const gt = useGT();
if (showMessage) {
return {gt('Hello!')}
;
}
return null;
}
```
For truly dynamic content that needs runtime translation, see the [Dynamic Content Guide](/docs/key-concepts/dynamic-content).
## Next steps
- [Dynamic Content Guide](/docs/key-concepts/dynamic-content) - Handle runtime translation
- [Shared Strings Guide](/docs/next/guides/shared-strings) - Organize reusable translations
- API References:
# gt-next: General Translation Next.js SDK: The T Component
URL: https://generaltranslation.com/en-US/docs/next/guides/t.mdx
---
title: The T Component
description: How to internationalize JSX components using the T component
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
The [`` component](/docs/next/api/components/t) is the primary tool for internationalizing JSX content in your Next.js application. It wraps your JSX elements and automatically translates them based on the user's locale.
**Tip:** With [auto JSX injection](/docs/cli/features/auto-jsx-injection) enabled, the compiler can automatically wrap your JSX in translation components at build time.
You may not need to add `` manually in most cases. Manual `` is still useful when you need fine-grained control, such as setting a specific `id` or `context`.
## Quickstart
Transform any static JSX content by wrapping it with [``](/docs/next/api/components/t):
```jsx
import { T } from 'gt-next';
// Before
function Greeting() {
return Hello, world!
;
}
// After
function Greeting() {
return Hello, world!
;
}
```
For dynamic content within [``](/docs/next/api/components/t), use [Variable Components](/docs/next/guides/variables) and [Branching Components](/docs/next/guides/branches).
## Basic usage
The [`` component](/docs/next/api/components/t) accepts any JSX content as children:
```jsx
// Simple text
Welcome to our app
// HTML elements
Page Title
// Complex nested JSX
Important: Please read carefully.
```
## Configuration options
### Adding context
Provide translation context for ambiguous terms:
```jsx
Click the toast to dismiss
```
## When to use T
Use [``](/docs/next/api/components/t) for **static content only**:
```jsx
// ✅ Static content works
Click here
Welcome to our site
// ❌ Dynamic content breaks
Hello {username}
Today is {new Date()}
// ✅ Use Variable components for dynamic content
Hello {username}
```
Variable and Branching components are designed to work inside [``](/docs/next/api/components/t) for dynamic content.
See [Variable Components](/docs/next/guides/variables) and [Branching Components](/docs/next/guides/branches) guides for details.
## Examples
### Simple elements
```jsx
// Basic text
Hello, world!
// Button with text
Submit Form
// Heading with styling
Welcome
```
### Complex components
```jsx
// Navigation menu
About Us
Contact
// Alert message
Your session expires in 5 minutes
```
### With variables
You can use variable components for localized formatting.
```jsx
// Combining static text with dynamic values
Welcome back, {user.name} !
You have {user.friends.length} friends online
Your birthday is {user.birthday}
Your balance is {user.balance}
```
Learn more about the [`` component](/docs/next/api/components/var) in the [Variable Components Guide](/docs/next/guides/variables).
## Production setup
### Build process
Add translation to your build pipeline:
```json title="package.json"
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
### Development vs production behavior
- **Development**: With a dev API key, translations happen on-demand when components render. You'll see real-time translation as you develop.
- **Production**: All translations are pre-built during the build stage and will be visible once your application is live.
Set your development API key in your environment to enable live translation during development. You can create one in the Dashboard under [API Keys](https://dash.generaltranslation.com/en-US/project/api-keys).
### Privacy considerations
Content in [``](/docs/next/api/components/t) components is sent to the GT API for translation. For sensitive data, use [Variable Components](/docs/next/guides/variables) to keep private information local:
```jsx
// Safe - sensitive data stays local
Welcome back, {username}
```
## How much to wrap in a single ``
Wrap **logical content blocks** — content that a translator would naturally read and translate together.
```jsx
// ✅ Good — related content wrapped together gives translators full context
Welcome to Our Platform
Get started in minutes with our simple setup process.
// ✅ Good — each card is an independent unit
{features.map((feature) => (
{feature.title}
{feature.description}
))}
// ❌ Too narrow — fragments the translation, loses context
Welcome to Our Platform
Get started in minutes with our simple setup process.
// ❌ Too wide — wrapping your entire page makes it harder to maintain
{/* ...hundreds of lines of JSX... */}
```
**Rule of thumb:** if text is visually or semantically related, wrap it in one ``. Only split when content is genuinely independent (e.g., a header vs. a footer).
Wrapping more content in a single `` gives translators better context, which produces more natural translations — some languages restructure sentences or need to reference nearby content.
## Common issues
### Component boundaries
[``](/docs/next/api/components/t) only translates direct children, not content inside other components:
```jsx
// ❌ Wrong - content inside components won't be translated
function MyComponent() {
return This won't be translated
;
}
This will be translated
{/* Content inside won't be translated */}
// ✅ Correct - wrap each component individually
function MyComponent() {
return This will be translated
;
}
This will be translated
```
### Nesting T components
```jsx
// ❌ Don't nest components
Hello world {/* Don't do this */}
```
### Dynamic content errors
The CLI will error on dynamic content in [``](/docs/next/api/components/t). Wrap dynamic values with Variable components:
```jsx
// ❌ Wrong - dynamic content breaks
Hello {username}
// ✅ Correct - use Variable components
Hello {username}
```
See the [Variable Components Guide](/docs/next/guides/variables) for handling dynamic values and the [Branching Components Guide](/docs/next/guides/branches) for conditional content.
## Next steps
**See it in action:** Check out the [`` component basics example app](https://github.com/gt-examples/t-component-basics) for a working demo — [live preview](https://t-component-basics.generaltranslation.dev).
- [Variable Components Guide](/docs/next/guides/variables) - Handle dynamic content within JSX translations
- [Branching Components Guide](/docs/next/guides/branches) - Add conditional logic to your translations
# gt-next: General Translation Next.js SDK: Variable Components
URL: https://generaltranslation.com/en-US/docs/next/guides/variables.mdx
---
title: Variable Components
description: How to use variable components for dynamic content within translations
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Variable components allow you to safely include dynamic content within [``](/docs/next/api/components/t) components. They handle formatting and localization locally without sending data to the translation API, making them perfect for sensitive information like usernames, account numbers, and financial data.
## Available components
- [``](/docs/next/api/components/var): Raw dynamic content without formatting
- [``](/docs/next/api/components/num): Numbers with locale-specific formatting
- [``](/docs/next/api/components/currency): Currency values with symbols and formatting
- [``](/docs/next/api/components/datetime): Dates and times with locale conventions
## Quickstart
Variable components work inside [``](/docs/next/api/components/t) to handle dynamic content:
```jsx
import { T, Var, Num, Currency, DateTime } from 'gt-next';
function UserProfile({ user }) {
return (
Welcome back, {user.name} !
You have {user.itemCount} items.
Balance: {user.balance}
Last login: {user.lastLogin}
);
}
```
## How variable components work
Variable components solve the dynamic content problem by:
1. **Wrapping dynamic values** so they can be used inside [``](/docs/next/api/components/t)
2. **Handling formatting locally** using the browser's built-in i18n APIs
3. **Keeping data private** - content is never sent to the translation API
4. **Providing localization** based on the user's current locale
```jsx
// ❌ This breaks - dynamic content in
Hello {username}
// ✅ This works - dynamic content wrapped
Hello {username}
```
## Component guide
### Var - Raw dynamic content
Use [``](/docs/next/api/components/var) for any dynamic content that doesn't need special formatting:
```jsx
// User information
Hello, {user.name} !
Your account ID is {user.accountId}
// Conditional rendering
Dashboard: {isAdmin ? : }
```
### Num - Formatted numbers
Use [``](/docs/next/api/components/num) for numbers that should follow locale formatting rules:
```jsx
// Basic number formatting
You have {itemCount} items in your cart.
// Standalone usage (equivalent to number.toLocaleString())
{totalItems}
// Custom formatting options
Distance: {distance} km
```
### Currency - Money values
Use [``](/docs/next/api/components/currency) for monetary amounts:
```jsx
// Basic currency formatting (defaults to "USD")
Your total is {total} .
// Different currencies
Price: {price}
// Custom formatting
{roundedAmount}
```
### DateTime - Dates and times
Use [``](/docs/next/api/components/datetime) for dates and times:
```jsx
// Basic date formatting
Order placed on {orderDate}
// Time formatting
Last updated: {timestamp}
// Custom date format
{eventDate}
```
## Privacy and security
### Data stays local
Variable components handle all formatting locally using the browser's [Intl APIs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl). **No dynamic content is sent to the translation API**, making them perfect for:
- User names and personal information
- Account numbers and IDs
- Financial data and balances
- Private timestamps and dates
```jsx
// Safe - sensitive data stays local
Account balance: {balance}
Last login: {lastLoginTime}
```
### Important exception
Be careful with nested [``](/docs/next/api/components/t) components inside variable components:
```jsx
// ⚠️ The inner content WILL be sent for translation
Hello, world! {/* This gets translated */}
{privateData} {/* This stays local */}
```
## Standalone usage
Variable components can be used outside of [``](/docs/next/api/components/t) for pure formatting:
```jsx
// These work like their respective .toLocale*() methods
{count} // count.toLocaleString()
{price} // price formatting
{date} // date.toLocaleDateString()
```
## Common issues
### Ignoring localization options
For [``](/docs/next/api/components/currency), make sure to pass the `currency` prop to specify the currency type. This ensures that the correct currency symbol and formatting are used when displaying the value:
```jsx
// ❌ Defaults to USD - may not be what users expect
The item costs {price}
// ✅ Explicitly specify the currency
The item costs {price}
```
Other components also have optional props that allow you to customize the formatting:
```jsx
// Basic formatting
{count} items in stock
// Custom formatting
{percentage} completion rate
// Date formatting
Last updated: {lastUpdate}
```
## Next steps
- [Branching Components Guide](/docs/next/guides/branches) - Add conditional logic to your translations
- [String Translation Guide](/docs/next/guides/strings) - Translate plain text without JSX
- API References:
- [`` Component](/docs/next/api/components/var)
- [`` Component](/docs/next/api/components/num)
- [`` Component](/docs/next/api/components/currency)
# gt-next: General Translation Next.js SDK: GT JSX Data Format
URL: https://generaltranslation.com/en-US/docs/next/reference/gt-jsx.mdx
---
title: GT JSX Data Format
description: Reference for the minified General Translation JSX data format
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
The GT JSX data format is a minified data format used by the General Translation libraries to represent translated UI in your React application.
## Introduction: JSX trees
React represents JSX trees as objects with the following structure:
```ts
type Element = {
type: string;
props: {
children: JSXTree[] | JSXTree;
// ...other props
};
// ...other attributes
};
type JSXTree = Element | string;
```
GT JSX is a compressed version of this JSX tree structure that is used by the General Translation libraries to represent translated UI in your React application.
## Reference
```ts
type Element = {
t?: string; // tag name
c?: (Element | Variable | string)[]; // children
i?: number; // GT ID of the element
d?: {
b?: Record; // branches
t?: "p" | "b"; // branch transformation type (plural or branch)
pl?: string; // placeholder
ti?: string; // title
alt?: string; // alt
arl?: string; // aria-label
arb?: string; // aria-labelledby
ard?: string; // aria-describedby
s?: Record; // style
};
}
type Variable = {
k: string; // key
v?: "v" | "n" | "c" | "d" | "rt"; // type
i?: number; // GT ID
}
type GTJSXTree = Element | Variable | string | (Element | Variable | string)[];
```
## GT JSX: Strings
The simplest form of GT JSX is a string, which represents a static string of text.
For example:
```jsx
Hello, world!
```
Would be represented in GT JSX as:
```ts
"Hello, world!"
```
Arrays of strings are also valid GT JSX:
```ts
["Hello, ", "world!"]
```
## GT JSX: Elements
GT represents JSX `Element` types in two possible ways.
### Variables
The first is a variable, a simple object that contains a key and an optional type. This is used for representing variables that can change at runtime.
```ts
type Variable = {
k: string; // `k` represents key, the name of the variable
v?: ( // represents the type of the variable, if left out is assumed as `v`
"v" | // `v`, a generic variable
"n" | // `n`, a number variable
"c" | // `c`, a currency variable
"d" | // `d`, a datetime variable
"rt" // `rt`, a relative time variable
);
i?: number; // GT ID of the variable
}
```
#### Example 1: Var
```jsx
Hello, {name} !
```
Would be represented in GT JSX as:
```ts
["Hello, ", { k: "_gt_var_1", i: 1 }, "!"]
```
Variables without a name prop are assigned unique internal names based on their GT ID
#### Example 2: Num
```jsx
The count is {count}
```
Would be represented in GT JSX as:
```ts
["The count is ", { k: "count", v: "n", i: 1 }]
```
#### Example 3: With name prop
```jsx
This product costs {amount}
```
Would be represented in GT JSX as:
```ts
["This product costs ", { k: "cost", v: "c", i: 1 }]
```
### Elements
Elements which are not variable are represented using the following data structure:
Note that all of these attributes are optional.
An empty object would represent a translated element in the same position as its original counterpart, with no translatable content among its descendants.
**In practice, `i` is always included.**
```ts
type Element = {
t?: string; // tag name
c?: GTJSXTree | GTJSXTree[]; // children
i?: number; // GT ID of the element
d?: { // data-_gt prop
b?: Record; // branches
t?: "p" | "b"; // branch transformation type (plural or branch)
pl?: string; // placeholder
ti?: string; // title
alt?: string; // alt
arl?: string; // aria-label
arb?: string; // aria-labelledby
ard?: string; // aria-describedby
s?: Record; // style
}
}
```
#### Example 1: Simple tags
```jsx
Hello, world !
```
Would be represented in GT JSX as:
```ts
["Hello, ", { c: "world", i: 1 }, "!"]
```
#### Example 2: Nested, with variables
```jsx
Hello , my name is {name}
```
Would be represented in GT JSX as:
```ts
[
{ t: "b", c: "Hello", i: 1 },
", my name is ",
{
t: "i",
c: { k: "_gt_var_3", i: 3 },
i: 2
}
]
```
#### Example 3: With Plural
```jsx
I have {count} item>}
other={<>I have {count} items>}
/>
```
Would be represented in GT JSX as:
```ts
{
i: 1,
d: {
t: "p",
b: {
one: {
c: ["I have", { k: "_gt_num_4", v: "n", i: 3 }, "item"],
i: 2
},
other: {
c: ["I have", { k: "_gt_num_4", v: "n", i: 3 }, "items"],
i: 2 // note the same ID is used for parallel branches
}
}
}
}
```
### GTJSX type
```ts
type GTJSXTree = Element | Variable | string | (Element | Variable | string)[];
```
## GT IDs
GT IDs are assigned to elements and variables in a JSX tree depth-first and sequentially, starting from 1.
When there are branch components like `` or ``, the same GT IDs are assigned to parallel branches. This is so that if there are more branches in one language than in another (e.g., languages where there are more plural forms), elements with the right props and logic can still be created.
## GT JSX JSON files
Each JSX Tree represents the children of a `` component.
Components are stored together in translation JSON files.
The type of the JSON object stored in these files corresponds to:
```ts
type GTJSXFile = {
[key: string]: GTJSXTree;
}
```
Where `key` is either user-defined or the hash of the original language `GTJSXTree`,
and `GTJSXTree` is the type of the GT JSX tree described above.
### Complete example
The written JSX:
```jsx
Alice's happy customer
```
Would be represented as the following JSX tree:
```ts
[
{
type: "b",
"props": {
"children": "Alice's"
}
},
" happy ",
{
type: "i",
"props": {
"children": "customer"
}
}
]
```
This would be minified into GT JSX as:
```ts
[{ t: "b", c: "Alice's", i: 1 }, " happy ", { t: "i", c: "customer", i: 2 }]
```
When translated into Spanish, the GT JSX would be:
```ts
[{ c: "El cliente", i: 2 }, " feliz ", { c: "de Alice", i: 1 }]
```
It would be stored in a file which looks like:
```json
{ "abc123": [{ "c": "El cliente", "i": 2 }, " feliz ", { "c": "de Alice", "i": 1 }] }
```
`abc123` is the hash of the original English GT JSX tree, not the Spanish translation.
When the Spanish translation is reconciled with the original JSX tree, the following would be produced:
```ts
[
{
type: "i",
"props": {
"children": "El cliente"
}
},
" feliz ",
{
type: "b",
"props": {
"children": "de Alice"
}
}
]
```
Which can then be displayed as the intended UI:
```jsx
<>El cliente feliz de Alice >
```
### Hashes
Hashing algorithm, hash length TBD
### Avoiding hashes at runtime
To avoid computing hashes at runtime, the libraries have an optional fallback mechanism where the user can specify an ID.
```jsx
Hello, world
```
If the ID is present in the translation JSON file, it will be used instead of the hash.
```json
{ "example": "Hello, world" }
```
# gt-next: General Translation Next.js SDK: Deploy to Production
URL: https://generaltranslation.com/en-US/docs/next/tutorials/quickdeploy.mdx
---
title: Deploy to Production
description: Let's deploy your Next.js app with GT
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Overview
This is a short tutorial to help you deploy your Next.js app with GT.
In total, this should take less than 5 minutes to complete.
We will do this in 3 steps:
Add your production API keys.
Run the `gt configure` command to configure your project.
Add the translate command to your build script.
## Prerequisites
We'll assume that you have already set up your Next.js app with GT.
If you haven't, first set up your project by following the [Quickstart Guide](/docs/next).
## Step 1: Add your production API keys 🔑
To deploy your app to production, you'll need to use a production API key.
From your [dashboard](https://generaltranslation.com/dashboard), go to **API Keys** in the sidebar.
Click on **Create API Key**, and add them to your production environment.
```bash copy
GT_API_KEY="YOUR_GT_API_KEY"
GT_PROJECT_ID="YOUR_GT_PROJECT_ID"
```
**Protect Your API Keys!**
Production keys should **only** ever be used in production.
Likewise, development keys should **only** ever be used in development.
*Never commit your API keys to a public repository!*
## Step 2: Run the `gt configure` command 🔧
If you've previously run the Setup Wizard, you can skip this step.
The setup wizard will have already run the `gt configure` command for you.
Run the `gt configure` command to configure your project.
```bash copy
npx gt configure
```
If you do not want your translations to be hosted on the GT CDN, select "No" when asked.
You will also need to configure the [`loadTranslations`](/docs/next/api/config/load-translations) function.
## Step 3: Add the translate command to your build script 🏗️
The last step is to add the [translate command](/docs/cli/translate) to your build script.
Make sure that the translate command comes before the build command.
```json title="package.json" copy
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
That's it! Now, when you deploy your app to production and run `npm run build`,
your project will be automatically translated and deployed alongside your app.
---
## Next steps
* See the [CLI docs](/docs/cli) for more information on the CLI tool.
* Learn about the different configuration options for the CLI tool [here](/docs/cli/configure).
* Read about the difference between production and development environments [here](/docs/next/concepts/environments).
# gt-next: General Translation Next.js SDK: Translating Strings
URL: https://generaltranslation.com/en-US/docs/next/tutorials/translating-strings.mdx
---
title: Translating Strings
description: How to translate strings
---
## Overview
This guide is a step-by-step tutorial on how to translate strings in your Next.js app using
[`useGT`](/docs/next/api/strings/use-gt), [`getGT`](/docs/next/api/strings/get-gt), and [`tx`](/docs/next/api/strings/tx).
## Prerequisites
We assume that you already have installed `gt-next` in your project and have followed or are currently following the [Quickstart Guide](/docs/next).
## Translating strings
### Client-side components
For any client-side strings, use [`useGT`](/docs/next/api/strings/use-gt).
Remember that `useGT` must be called within a child component of [``](/docs/next/api/components/gtprovider).
```jsx title="src/components/MyComponent.jsx" copy
import { useGT } from 'gt-next';
export default function MyComponent() {
const gt = useGT(); // [!code highlight]
return (
{gt('This is a string that gets translated')} // [!code highlight]
);
}
```
### Server-side components
For any server-side strings, use [`getGT`](/docs/next/api/strings/get-gt).
```jsx title="src/pages/index.jsx" copy
import { getGT } from 'gt-next/server';
export default async function Home() {
const gt = await getGT(); // [!code highlight]
return (
{gt('This is a string that gets translated')} // [!code highlight]
);
}
```
**Note:**
When in development, if you are translating content at runtime, you will have to refresh the page to see the translated version of a string from [`getGT`](/docs/next/api/strings/get-gt).
**This does not happen in production.**
### Adding variables
Variables are values that may change, but do not get translated.
To add variables to your strings, use the following pattern:
```jsx title="MyComponent.jsx" copy
import { useGT } from 'gt-next';
export default function MyComponent() {
const gt = useGT();
return (
{gt('Hello there, {username}', { variables: { username: 'Brian123' }})} // [!code highlight]
);
}
```
This works with both [`useGT`](/docs/next/api/strings/use-gt) and [`getGT`](/docs/next/api/strings/get-gt).
### Dynamic content
Say that you have a string that changes.
You can use the [`tx`](/docs/next/api/strings/tx) function to translate the string at runtime.
```jsx title="MyComponent.jsx" copy
import { tx } from 'gt-next/server';
export default async function MyComponent({ username }) {
const translation = await tx(`Hello, ${username}. How is your day?`); // [!code highlight]
return (
{translation} // [!code highlight]
);
}
```
**Note:**
The [`tx`](/docs/next/api/strings/tx) function is only available on the server-side, and should only be used when necessary.
Runtime translation often creates a delay.
Use [`getGT`](/docs/next/api/strings/get-gt) or [`useGT`](/docs/next/api/strings/use-gt) whenever possible to translate before deployment.
---
## Notes
* For translating strings, use [`useGT`](/docs/next/api/strings/use-gt), [`getGT`](/docs/next/api/strings/get-gt), and [`tx`](/docs/next/api/strings/tx).
* `useGT` and `getGT` translate before deployment, whereas `tx` translates at runtime. Use `tx` sparingly.
* Variables can be added to strings using the `{ variables: { key: value } }` pattern.
## Next steps
* Return to the [Quickstart Guide](/docs/next) to finish setting up your project for translation.
* See the API reference for [`useGT`](/docs/next/api/strings/use-gt), [`getGT`](/docs/next/api/strings/get-gt), and [`tx`](/docs/next/api/strings/tx).
# node: getDefaultLocale
URL: https://generaltranslation.com/en-US/docs/node/api/get-default-locale.mdx
---
title: getDefaultLocale
description: API reference for the getDefaultLocale function
---
## Overview
The `getDefaultLocale` function returns the default locale configured in [`initializeGT`](/docs/node/api/initialize-gt).
```js
import { getDefaultLocale } from 'gt-node';
const defaultLocale = getDefaultLocale(); // 'en-US'
```
## Reference
### Parameters
None.
### Returns
`string` — The default BCP 47 [locale code](/docs/core/locales) (e.g., `'en-US'`).
---
## Examples
### Basic usage
```js title="handler.js"
import { getDefaultLocale } from 'gt-node';
app.get('/api/info', (req, res) => {
res.json({ defaultLocale: getDefaultLocale() });
});
```
---
## Next steps
- See [`getLocale`](/docs/node/api/get-locale) for the current request locale.
- See [`getLocales`](/docs/node/api/get-locales) for all supported locales.
# node: getGT
URL: https://generaltranslation.com/en-US/docs/node/api/get-gt.mdx
---
title: getGT
description: API reference for the getGT string translation function
---
## Overview
The `getGT` function is an async function that returns a translation function for translating strings.
It resolves translations registered at build time by the GT compiler.
```js
import { getGT } from 'gt-node';
const gt = await getGT();
const greeting = gt('Hello, world!');
```
**Request Context Required:**
`getGT` must be called within a [`withGT`](/docs/node/api/with-gt) callback so it knows which locale to use.
## Reference
### Parameters
None.
### Returns
A promise that resolves to a translation function `gt`:
```ts
Promise<(content: string, options?: InlineTranslationOptions) => string>
```
| Name | Type | Description |
| ---- | ---- | ----------- |
| `content` | `string` | The string to translate. |
| `options?` | `InlineTranslationOptions` | Optional translation options (variables, context, etc.). |
The `gt` function returns the translated string, or the original string if no translation is found.
#### `InlineTranslationOptions`
| Prop | Type | Description |
| ---- | ---- | ----------- |
| `$context?` | `string` | Additional context to help disambiguate translations. |
| `$id?` | `string` | A custom ID for the translation entry. |
| `$maxChars?` | `number` | Maximum character count for the translation. |
| Other keys | `any` | Variable values to interpolate into the string using `{key}` syntax. |
---
## Examples
### Simple translation
```js title="handler.js"
import { withGT, getGT } from 'gt-node';
function handleRequest(locale: string) {
return withGT(locale, async () => {
const gt = await getGT();
return gt('Hello, world!');
});
}
```
### With variables
Use `{variableName}` syntax in the string and pass values in the options object:
```js title="handler.js"
import { withGT, getGT } from 'gt-node';
function handleGreeting(locale: string, name: string) {
return withGT(locale, async () => {
const gt = await getGT();
return gt('Hello, {name}!', { name });
});
}
```
### With ICU message format
`gt-node` supports ICU message format for advanced formatting:
```js title="handler.js"
const gt = await getGT();
const balance = gt(
'Your balance: {amount, number, ::currency/USD}',
{ amount: 1234.56 }
);
```
---
## Notes
- `getGT` returns a **build-time** translation function. Strings are translated during the CD process before deployment.
- In development, translations happen on demand (requires a Dev API key).
- If no translation is found, the original string is returned as a fallback.
## Next steps
- See [`getMessages`](/docs/node/api/get-messages) for resolving pre-registered messages.
- See [`withGT`](/docs/node/api/with-gt) for setting up the locale context.
# node: getLocaleProperties
URL: https://generaltranslation.com/en-US/docs/node/api/get-locale-properties.mdx
---
title: getLocaleProperties
description: API reference for the getLocaleProperties function
---
## Overview
The `getLocaleProperties` function returns metadata about a given locale, including its name, native name, language, region, and script information.
```js
import { getLocaleProperties } from 'gt-node';
const props = getLocaleProperties('en-US');
console.log(props.name); // 'American English'
```
## Reference
### Parameters
| Parameter | Type | Description |
| --- | --- | --- |
| `locale` | `string` | A BCP 47 locale code (e.g., `'en-US'`, `'ja'`). When not provided, uses the current locale. |
### Returns
A `LocaleProperties` object with the following fields:
| Field | Type | Description |
| --- | --- | --- |
| `code` | `string` | The locale code (e.g., `'en-US'`). |
| `name` | `string` | The English name of the locale (e.g., `'American English'`). |
| `nativeName` | `string` | The name in the locale's own language (e.g., `'American English'`). |
| `languageCode` | `string` | The language subtag (e.g., `'en'`). |
| `languageName` | `string` | The English name of the language (e.g., `'English'`). |
| `nativeLanguageName` | `string` | The language name in its own language (e.g., `'English'`). |
| `nameWithRegionCode` | `string` | The locale name including region (e.g., `'English (US)'`). |
| `nativeNameWithRegionCode` | `string` | The native locale name including region. |
| `regionCode` | `string` | The region subtag (e.g., `'US'`). |
| `regionName` | `string` | The English name of the region (e.g., `'United States'`). |
| `nativeRegionName` | `string` | The region name in the locale's own language. |
| `scriptCode` | `string` | The script subtag (e.g., `'Latn'`). |
| `scriptName` | `string` | The English name of the script (e.g., `'Latin'`). |
| `nativeScriptName` | `string` | The script name in the locale's own language. |
| `maximizedCode` | `string` | The fully expanded locale code (e.g., `'en-Latn-US'`). |
---
## Examples
### Basic usage
```js title="handler.js"
import { getLocaleProperties } from 'gt-node';
app.get('/api/locale-info', (req, res) => {
const props = getLocaleProperties('ja');
res.json({
name: props.name, // 'Japanese'
nativeName: props.nativeName, // '日本語'
script: props.scriptName, // 'Japanese'
});
});
```
---
## Notes
- This function is synchronous — it does not need to be awaited.
- Useful for building locale selectors or displaying locale metadata to users.
## Next steps
- See [`getLocale`](/docs/node/api/get-locale) for the current request locale.
- Learn more about [locale codes](/docs/core/locales).
# node: getLocale
URL: https://generaltranslation.com/en-US/docs/node/api/get-locale.mdx
---
title: getLocale
description: API reference for the getLocale function
---
## Overview
The `getLocale` function returns the current locale for the active request context.
```js
import { getLocale } from 'gt-node';
const locale = getLocale(); // 'en-US'
```
**Request Context Required:**
`getLocale` must be called within a [`withGT`](/docs/node/api/with-gt) callback so it knows which locale to use.
## Reference
### Parameters
None.
### Returns
`string` — The current BCP 47 [locale code](/docs/core/locales) (e.g., `'en-US'`).
---
## Examples
### Basic usage
```js title="handler.js"
import { withGT, getLocale } from 'gt-node';
app.use((req, res, next) => {
const locale = req.headers['accept-language']?.split(',')[0] || 'en-US';
withGT(locale, () => {
console.log(getLocale()); // 'en-US'
next();
});
});
```
---
## Next steps
- See [`getLocales`](/docs/node/api/get-locales) for the full list of supported locales.
- See [`getLocaleProperties`](/docs/node/api/get-locale-properties) for locale metadata.
# node: getLocales
URL: https://generaltranslation.com/en-US/docs/node/api/get-locales.mdx
---
title: getLocales
description: API reference for the getLocales function
---
## Overview
The `getLocales` function returns the list of supported locales configured in [`initializeGT`](/docs/node/api/initialize-gt).
```js
import { getLocales } from 'gt-node';
const locales = getLocales(); // ['en-US', 'es', 'fr']
```
## Reference
### Parameters
None.
### Returns
`string[]` — An array of BCP 47 [locale codes](/docs/core/locales) representing the supported locales.
---
## Examples
### Basic usage
```js title="handler.js"
import { getLocales } from 'gt-node';
app.get('/api/locales', (req, res) => {
res.json({ supportedLocales: getLocales() });
});
```
---
## Next steps
- See [`getLocale`](/docs/node/api/get-locale) for the current request locale.
- See [`getDefaultLocale`](/docs/node/api/get-default-locale) for the default locale.
# node: getMessages
URL: https://generaltranslation.com/en-US/docs/node/api/get-messages.mdx
---
title: getMessages
description: API reference for the getMessages function
---
## Overview
The `getMessages` function is an async function that returns a resolver for pre-registered messages.
Use it together with [`msg`](/docs/node/api/strings/msg) (imported from `gt-node`) to register strings at build time and resolve their translations at runtime.
```js
import { msg, getMessages } from 'gt-node';
// Register at build time (or module scope)
const greeting = msg('Hello, world!');
// Resolve at runtime
const m = await getMessages();
const translated = m(greeting);
```
**Request Context Required:**
`getMessages` must be called within a [`withGT`](/docs/node/api/with-gt) callback so it knows which locale to use.
## Reference
### Parameters
None.
### Returns
A promise that resolves to a message resolution function `m`:
```ts
Promise<(encodedMsg: string | null | undefined, options?: InlineResolveOptions) => string | null | undefined>
```
| Name | Type | Description |
| ---- | ---- | ----------- |
| `encodedMsg` | `string \| null \| undefined` | An encoded message string returned by `msg()`. Returns `null`/`undefined` if given `null`/`undefined`. |
| `options?` | `InlineResolveOptions` | Optional variable values to interpolate into the resolved message. |
---
## Examples
### Basic usage
```js title="messages.js"
import { msg } from 'gt-node';
// Register messages at module scope
export const GREETING = msg('Hello, world!');
export const WELCOME = msg('Welcome, {name}!');
```
```js title="handler.js"
import { withGT, getMessages } from 'gt-node';
import { GREETING, WELCOME } from './messages';
function handleRequest(locale: string) {
return withGT(locale, async () => {
const m = await getMessages();
return {
greeting: m(GREETING),
welcome: m(WELCOME, { name: 'Alice' }),
};
});
}
```
### With variables
Pass variables as the second argument to interpolate values:
```js title="handler.js"
import { msg, getMessages, withGT } from 'gt-node';
const ORDER_STATUS = msg('Order {orderId} is {status}.');
function getOrderMessage(locale: string, orderId: string, status: string) {
return withGT(locale, async () => {
const m = await getMessages();
return m(ORDER_STATUS, { orderId, status });
});
}
```
---
## Notes
- `msg` registers a string for build-time translation. `getMessages` resolves it at runtime.
- This pattern is useful for strings defined at module scope (constants, enums, error messages) that need to be translated per-request.
- If `null` or `undefined` is passed to `m`, it returns `null` or `undefined` respectively.
## Next steps
- See [`getGT`](/docs/node/api/get-gt) for translating inline strings directly.
- See [`withGT`](/docs/node/api/with-gt) for setting up the locale context.
# node: getRequestLocale
URL: https://generaltranslation.com/en-US/docs/node/api/get-request-locale.mdx
---
title: getRequestLocale
description: API reference for the getRequestLocale function
---
## Overview
The `getRequestLocale` function extracts the preferred locale from a request's `Accept-Language` header and matches it against your configured locales.
```js
import { getRequestLocale } from 'gt-node';
const locale = getRequestLocale(req); // 'fr'
```
**Requires initialization:**
Call [`initializeGT`](/docs/node/api/initialize-gt) before using `getRequestLocale` so it knows which locales are supported.
## Reference
### Parameters
.',
optional: false,
},
}}
/>
### Returns
`string` — The best matching BCP 47 [locale code](/docs/core/locales) from your configured locales, or the `defaultLocale` if no match is found.
---
## Examples
### Express middleware
```js title="middleware/locale.js"
import { withGT, getRequestLocale } from 'gt-node';
export function localeMiddleware(req, res, next) {
const locale = getRequestLocale(req);
withGT(locale, () => next());
}
```
### Combining with other strategies
Use `getRequestLocale` as a fallback when no explicit preference is set:
```js title="middleware/locale.js"
import { withGT, getRequestLocale } from 'gt-node';
export function localeMiddleware(req, res, next) {
const locale =
req.query.lang ||
req.cookies?.locale ||
getRequestLocale(req);
withGT(locale, () => next());
}
```
---
## Next steps
- See [`getLocale`](/docs/node/api/get-locale) to read the locale inside a `withGT` context.
- See the [Locale Detection & Middleware](/docs/node/guides/middleware) guide for full middleware patterns.
# node: getTranslations
URL: https://generaltranslation.com/en-US/docs/node/api/get-translations.mdx
---
title: getTranslations
description: API reference for the getTranslations dictionary translation function
---
## Overview
`getTranslations` returns a translation function `t` that resolves entries from a [dictionary](/docs/next/guides/dictionaries).
Use it to translate pre-defined strings by their dictionary key.
```js
import { getTranslations } from 'gt-node';
const t = await getTranslations();
t('greeting.hello'); // "Hello!"
```
**Request context required:**
`getTranslations` must be called within a [`withGT`](/docs/node/api/with-gt) callback so it knows which locale to use.
## Reference
### Parameters
None.
### Returns
A promise that resolves to a translation function `t`:
```ts
Promise
```
The `t` function accepts a dictionary key and optional interpolation options:
| Name | Type | Description |
| --- | --- | --- |
| `id` | `string` | The dot-separated path to a dictionary entry. |
| `options?` | `DictionaryTranslationOptions` | Variables for interpolation. |
**Returns:** `string` — the translated (or source-language fallback) text.
If the key does not exist in the source dictionary, `t()` throws an error.
If the key exists in the source dictionary but has no translation for the current locale, `t()` returns the source text.
### `t.obj()`
Returns an entire subtree of the dictionary as an object instead of a single string.
```ts
t.obj(id: string): DictionaryObjectTranslation
```
| Name | Type | Description |
| --- | --- | --- |
| `id` | `string` | The dot-separated path to a dictionary subtree. |
**Returns:** A nested object matching the dictionary structure, with translated values where available and source-language fallbacks elsewhere.
---
## Setup
### Automatic (recommended)
Create a `dictionary.json` file in your project root:
```json title="dictionary.json"
{
"greeting": {
"hello": "Hello!"
},
"user": {
"welcome": "Welcome, {name}!"
}
}
```
When you run `npx gtx translate`, the CLI automatically detects `dictionary.json` and translates it for your configured locales.
Then initialize GT with the dictionary:
```ts
import { initializeGT } from 'gt-node';
import dictionary from './dictionary.json';
initializeGT({
dictionary,
defaultLocale: 'en-US',
locales: ['en-US', 'es', 'fr'],
});
```
### Custom dictionary loader
If you manage your own translated dictionaries, pass a `loadDictionary` function to [`initializeGT`](/docs/node/api/initialize-gt):
```ts
import { initializeGT } from 'gt-node';
import dictionary from './dictionary.json';
initializeGT({
dictionary,
loadDictionary: async (locale) => {
const dict = await import(`./locales/${locale}.json`);
return dict.default;
},
});
```
Translations loaded via `loadDictionary` take precedence over GT-generated translations.
---
## Examples
### Basic usage
```ts
import { getTranslations } from 'gt-node';
const t = await getTranslations();
t('greeting.hello'); // "Hello!"
```
### Variable interpolation
```ts
const t = await getTranslations();
t('user.welcome', { name: 'Alice' }); // "Welcome, Alice!"
```
### Object lookup with `t.obj()`
```ts
const t = await getTranslations();
const errors = t.obj('errors');
// { notFound: "Page not found", unauthorized: "Access denied" }
```
---
## Notes
- `getTranslations` is the dictionary-based counterpart to [`getMessages`](/docs/node/api/get-messages), which is used for inline `msg()` strings.
- For the Next.js equivalent, see [`getTranslations` in gt-next](/docs/next/api/dictionary/get-translations).
# node: initializeGT
URL: https://generaltranslation.com/en-US/docs/node/api/initialize-gt.mdx
---
title: initializeGT
description: API reference for the initializeGT setup function
---
## Overview
The `initializeGT` function configures General Translation for use in a Node.js runtime.
It must be called once before any translation functions are used.
```js
import { initializeGT } from 'gt-node';
initializeGT({
defaultLocale: 'en-US',
locales: ['en-US', 'es', 'fr'],
projectId: 'your-project-id',
});
```
**Required setup:**
`initializeGT` must be called before using `withGT`, `getGT`, `getMessages`, `getTranslations`, or any other translation function.
Call it once during your server's initialization (e.g., at the top of your entry file).
## Reference
### Parameters
>',
optional: true,
},
"enableI18n?": {
type: 'boolean',
optional: true,
},
"cacheExpiryTime?": {
type: 'number',
optional: true,
},
}}
/>
### Description
| Prop | Description |
| ---- | ----------- |
| `defaultLocale` | The default locale for your application. Defaults to `'en-US'`. |
| `locales` | An array of locale codes your application supports. |
| `projectId` | Your General Translation project ID, required for cloud translation services. |
| `devApiKey` | API key for development environment on-demand translations. |
| `cacheUrl` | URL of the GT cache service. Set to `null` to disable. |
| `runtimeUrl` | URL of the GT runtime translation service. Set to `null` to disable. |
| `dictionary` | A source-language dictionary object for use with [`getTranslations`](/docs/node/api/get-translations). |
| `loadDictionary` | An async function that loads a translated dictionary for a given locale. Requires `dictionary` to be set. |
| `loadTranslations` | A custom function to load translations from your own source. |
| `customMapping` | A mapping of custom locale codes to standard locale codes or locale properties. |
| `enableI18n` | Whether to enable i18n features. |
| `cacheExpiryTime` | Time in milliseconds before cached translations expire. |
### Returns
`void`
---
## Examples
### Basic setup
```js title="server.js"
import { initializeGT } from 'gt-node';
initializeGT({
defaultLocale: 'en-US',
locales: ['en-US', 'es', 'fr', 'ja'],
projectId: process.env.GT_PROJECT_ID,
});
```
### With a custom translation loader
```js title="server.js"
import { initializeGT } from 'gt-node';
initializeGT({
defaultLocale: 'en-US',
locales: ['en-US', 'es'],
loadTranslations: async (locale) => {
const res = await fetch(`https://my-api.com/translations/${locale}`);
return res.json();
},
});
```
---
## Notes
- `initializeGT` must be called **once** before any translation functions are used.
- If using GT cloud services, provide `projectId`. For development, also provide `devApiKey`.
- The `loadTranslations` option lets you bring your own translation source instead of using GT's CDN.
## Next steps
- See [`withGT`](/docs/node/api/with-gt) to provide locale context for each request.
- See [`getGT`](/docs/node/api/get-gt) and [`getMessages`](/docs/node/api/get-messages) for translating inline strings.
- See [`getTranslations`](/docs/node/api/get-translations) for dictionary-based translations.
# node: withGT
URL: https://generaltranslation.com/en-US/docs/node/api/with-gt.mdx
---
title: withGT
description: API reference for the withGT request wrapper
---
## Overview
The `withGT` function wraps a callback to provide locale context for translation functions.
In a Node.js server, each request typically serves a different user with a different locale.
`withGT` sets the locale for all translation functions called within the callback.
```js
import { withGT } from 'gt-node';
app.get('/api/greeting', (req, res) => {
withGT(req.locale, () => {
// Translation functions inside here use req.locale
});
});
```
**Request Context:**
`withGT` uses async local storage under the hood to scope the locale to the current request.
All calls to `getGT` and `getMessages` within the callback will use the provided locale.
## Reference
### Parameters
T',
optional: false,
},
}}
/>
### Description
| Param | Description |
| ----- | ----------- |
| `locale` | A [locale code](/docs/core/locales) (e.g., `'es'`, `'fr-CA'`) to use for translations within the callback. |
| `fn` | A callback function to execute with the given locale context. Can be synchronous or asynchronous. |
### Returns
`T` — the return value of the callback function `fn`.
---
## Examples
### Express middleware
```js title="server.js"
import express from 'express';
import { initializeGT, withGT, getGT } from 'gt-node';
initializeGT({
defaultLocale: 'en-US',
locales: ['en-US', 'es', 'fr'],
projectId: process.env.GT_PROJECT_ID,
});
const app = express();
app.use((req, res, next) => {
const locale = req.headers['accept-language']?.split(',')[0] || 'en-US';
withGT(locale, () => {
next();
});
});
app.get('/api/greeting', async (req, res) => {
const gt = await getGT();
res.json({ message: gt('Hello, world!') });
});
```
### Wrapping an async handler
```js title="handler.js"
import { withGT, getGT } from 'gt-node';
export async function handleRequest(locale: string) {
return withGT(locale, async () => {
const gt = await getGT();
return gt('Welcome to our app!');
});
}
```
---
## Notes
- `initializeGT` must be called before `withGT` is used. If not, an error will be thrown.
- The locale context is scoped to the callback and does not leak to other concurrent requests.
- `withGT` works with both synchronous and asynchronous callbacks.
## Next steps
- See [`initializeGT`](/docs/node/api/initialize-gt) for initial setup.
- See [`getGT`](/docs/node/api/get-gt) for translating strings within a request context.
# node: Error Handling & Fallbacks
URL: https://generaltranslation.com/en-US/docs/node/guides/error-handling.mdx
---
title: Error Handling & Fallbacks
description: What happens when translations aren't available and how to handle it
---
## Default fallback behavior
When a translation isn't available — whether the locale is unsupported, the translation file is missing, or the CDN is unreachable — `gt-node` returns the original string in your `defaultLocale`. Your app never crashes due to a missing translation.
```js
import { getGT } from 'gt-node';
app.get('/api/greeting', async (req, res) => {
const gt = await getGT();
// If Spanish translation isn't available, returns the English original
res.json({ message: gt('Hello, world!') });
});
```
This fallback is automatic. You don't need to wrap translation calls in try/catch for missing translations.
## Missing locales
If a request comes in for a locale you haven't configured in `locales`, the translation functions fall back to `defaultLocale`:
```js
initializeGT({
defaultLocale: 'en',
locales: ['en', 'es', 'fr'], // Japanese not included
});
// Request with Accept-Language: ja
// gt('Hello!') → returns 'Hello!' (English fallback)
```
To support a new locale, add it to your `locales` array and regenerate translations:
```bash
npx gt translate
```
## Checking available locales
Use [`getLocales()`](/docs/node/api/get-locales) and [`getDefaultLocale()`](/docs/node/api/get-default-locale) to inspect what's available at runtime:
```js
import { getLocales, getDefaultLocale } from 'gt-node';
app.get('/api/locales', (req, res) => {
res.json({
supported: getLocales(),
default: getDefaultLocale(),
});
});
```
## Handling translation in API responses
When building APIs, you may want to explicitly indicate when content is in a fallback language:
```js
import { getGT, getLocale, getDefaultLocale } from 'gt-node';
app.get('/api/greeting', async (req, res) => {
const gt = await getGT();
const locale = getLocale();
const defaultLocale = getDefaultLocale();
res.json({
message: gt('Hello, world!'),
locale,
isFallback: locale !== defaultLocale,
});
});
```
## Debugging translations
### Check which locale is active
```js
import { getLocale } from 'gt-node';
app.use((req, res, next) => {
console.log(`[i18n] Request locale: ${getLocale()}`);
next();
});
```
### Verify translations are loaded
In development, `gt-node` translates on-demand via the API. If translations seem missing:
1. Confirm your `GT_API_KEY` and `GT_PROJECT_ID` are set
2. Check that the locale is in your `locales` array
3. Look for errors in your server logs
### Production checklist
Before deploying, verify:
- [ ] `npx gt translate` runs successfully in your build script
- [ ] All target locales are listed in `gt.config.json`
- [ ] `GT_PROJECT_ID` is set in production environment
- [ ] `GT_API_KEY` is set in production environment (for `npx gt translate`)
In development, translations happen on-demand and may be slow. In production, always pre-generate translations with `npx gt translate` — see the [CLI docs](/docs/cli/translate).
## Next steps
- [String Translation Patterns](/docs/node/guides/strings) — the two translation approaches
- [Local Translation Storage](/docs/node/guides/local-tx) — bundle translations for offline use
- [`getLocale` API reference](/docs/node/api/get-locale)
# node: Local Translation Storage
URL: https://generaltranslation.com/en-US/docs/node/guides/local-tx.mdx
---
title: Local Translation Storage
description: Store translations in your app bundle instead of fetching from a CDN
---
## What are local translations?
By default, `gt-node` fetches translations from the General Translation CDN at runtime. With local translations, you bundle translation files directly into your app — no external requests needed.
**Default behavior:** GT uses CDN storage by default. Only switch to local storage if you need the specific benefits it provides.
## Trade-offs
### Benefits of local translations
- **Faster responses**: No network requests to fetch translations at runtime
- **No reliance on external services**: Your app works independently of CDN availability
- **Works offline**: Translations are part of your deployment artifact
### Drawbacks of local translations
- **Increased bundle size**: Every supported locale adds to your deployment size
- **Redeploy to update**: Changing a translation requires a new deployment
## Setup
### Step 1: Create a load function
Write a function that loads a translation JSON file given a locale:
```js title="loadTranslations.js"
import { readFile } from 'fs/promises';
import path from 'path';
export default async function loadTranslations(locale) {
const filePath = path.join(process.cwd(), 'translations', `${locale}.json`);
const data = await readFile(filePath, 'utf-8');
return JSON.parse(data);
}
```
### Step 2: Pass it to `initializeGT`
```js title="server.js"
import { initializeGT } from 'gt-node';
import loadTranslations from './loadTranslations.js';
initializeGT({
defaultLocale: 'en',
locales: ['en', 'es', 'fr', 'ja'],
projectId: process.env.GT_PROJECT_ID,
loadTranslations,
});
```
### Step 3: Configure the CLI
Run the configuration command and select local storage:
```bash
npx gt configure
```
When prompted:
- **Save to CDN?** Select "No"
- **Translation directory:** Enter `./translations`
### Step 4: Generate translations
```bash
npx gt translate
```
This downloads translation files into your `translations/` directory.
## Build integration
Add translation generation to your build script so translations are always fresh:
```json title="package.json"
{
"scripts": {
"build": "npx gt translate && "
}
}
```
### CI/CD pipeline
```yaml title=".github/workflows/deploy.yml"
- name: Generate Translations
run: npx gt translate
- name: Build Application
run: npm run build
```
## Common issues
### Missing translation files
Always generate translations before building:
```bash
# ❌ Build without translations
node server.js
# ✅ Generate translations first
npx gt translate && node server.js
```
### File path errors
Make sure the path in your load function matches the CLI's output directory:
```js
// ❌ Wrong path
const filePath = path.join(process.cwd(), 'public', `${locale}.json`);
// ✅ Match your configured directory
const filePath = path.join(process.cwd(), 'translations', `${locale}.json`);
```
Local storage works best for apps with stable translations that don't need frequent updates.
## Next steps
- [CLI `translate` command](/docs/cli/translate) — translation generation reference
- [CLI configuration](/docs/cli/reference/config) — configure output directory and storage mode
- [String Translation Patterns](/docs/node/guides/strings) — how to translate content
# node: Locale Detection & Middleware
URL: https://generaltranslation.com/en-US/docs/node/guides/middleware.mdx
---
title: Locale Detection & Middleware
description: How to detect the user's locale and set it per request with withGT
---
Every translation function in `gt-node` needs to know which locale the current request is targeting. [`withGT`](/docs/node/api/with-gt) sets this context using async local storage — wrap your request handler, and all downstream translation calls automatically use the right locale.
## How `withGT` works
`withGT` takes a locale string and a callback. Inside that callback, [`getGT()`](/docs/node/api/get-gt), [`getMessages()`](/docs/node/api/get-messages), and [`getLocale()`](/docs/node/api/get-locale) all read from the locale you set:
```js
import { withGT, getLocale } from 'gt-node';
app.use((req, res, next) => {
const locale = detectLocale(req);
withGT(locale, () => next());
});
```
Translation functions called outside a `withGT` context will use the `defaultLocale`. Always wrap your request handling in `withGT`.
## Locale detection strategies
### Accept-Language header
Use [`getRequestLocale`](/docs/node/api/get-request-locale) to parse the `Accept-Language` header and match it against your configured locales:
```js
import { getRequestLocale } from 'gt-node';
function detectLocale(req) {
return getRequestLocale(req);
}
```
`getRequestLocale` handles quality values, wildcard entries, and language-region matching automatically.
### Cookie-based
Persist the user's language choice across sessions:
```js
import cookieParser from 'cookie-parser';
app.use(cookieParser());
function detectLocale(req) {
return req.cookies.locale || 'en';
}
// Endpoint to set language preference
app.post('/api/set-language', (req, res) => {
res.cookie('locale', req.body.locale, { maxAge: 365 * 24 * 60 * 60 * 1000 });
res.json({ ok: true });
});
```
### URL parameter
Extract locale from the URL path (e.g. `/es/api/greeting`):
```js
function detectLocale(req) {
const segments = req.path.split('/').filter(Boolean);
const supported = new Set(['es', 'fr', 'ja', 'de']);
if (segments[0] && supported.has(segments[0])) {
return segments[0];
}
return 'en';
}
```
### Query parameter
Use a `?lang=` query parameter:
```js
function detectLocale(req) {
return req.query.lang || 'en';
}
```
## Chaining strategies
In practice, you'll want to try multiple strategies in priority order:
```js
function detectLocale(req) {
// 1. Explicit query parameter (highest priority)
if (req.query.lang) return req.query.lang;
// 2. Cookie (user's saved preference)
if (req.cookies?.locale) return req.cookies.locale;
// 3. Accept-Language header (browser default)
const acceptLang = req.headers['accept-language']?.split(',')[0];
if (acceptLang) return acceptLang;
// 4. Default
return 'en';
}
```
## Express middleware
A complete Express middleware setup:
```js title="middleware/locale.js"
import { withGT } from 'gt-node';
export function localeMiddleware(req, res, next) {
const locale =
req.query.lang ||
req.cookies?.locale ||
req.headers['accept-language']?.split(',')[0] ||
'en';
withGT(locale, () => next());
}
```
```js title="server.js"
import express from 'express';
import cookieParser from 'cookie-parser';
import { initializeGT } from 'gt-node';
import { localeMiddleware } from './middleware/locale.js';
initializeGT({
defaultLocale: 'en',
locales: ['en', 'es', 'fr', 'ja'],
projectId: process.env.GT_PROJECT_ID,
});
const app = express();
app.use(cookieParser());
app.use(localeMiddleware);
```
## Fastify middleware
The same pattern works with Fastify using a `preHandler` hook:
```js title="server.js"
import Fastify from 'fastify';
import cookie from '@fastify/cookie';
import { initializeGT, withGT, getGT } from 'gt-node';
initializeGT({
defaultLocale: 'en',
locales: ['en', 'es', 'fr', 'ja'],
projectId: process.env.GT_PROJECT_ID,
});
const app = Fastify();
await app.register(cookie);
app.addHook('preHandler', (req, reply, done) => {
const locale =
req.query.lang ||
req.cookies?.locale ||
req.headers['accept-language']?.split(',')[0] ||
'en';
withGT(locale, () => done());
});
app.get('/api/greeting', async (req, reply) => {
const gt = await getGT();
return { message: gt('Hello, world!') };
});
app.listen({ port: 3000 });
```
## Reading the current locale
Use [`getLocale()`](/docs/node/api/get-locale) anywhere inside a `withGT` context to read back the resolved locale:
```js
import { getLocale } from 'gt-node';
app.get('/api/info', async (req, res) => {
const locale = getLocale();
res.json({ currentLocale: locale });
});
```
## Next steps
- [`withGT` API reference](/docs/node/api/with-gt)
- [`getLocale` API reference](/docs/node/api/get-locale)
- [`getRequestLocale` API reference](/docs/node/api/get-request-locale)
- [String Translation Patterns](/docs/node/guides/strings) — how to translate content
- [Local Translation Storage](/docs/node/guides/local-tx) — bundle translations with your app
# node: String Translation Patterns
URL: https://generaltranslation.com/en-US/docs/node/guides/strings.mdx
---
title: String Translation Patterns
description: Two approaches to translating strings in Node.js — inline and pre-registered
---
There are three ways to translate strings in `gt-node`:
1. **Inline with `getGT()`** — translate strings directly inside request handlers (build-time)
2. **Pre-registered with `msg()` / `getMessages()`** — define strings at module scope, resolve at runtime (build-time)
3. **On-demand with `tx()`** — translate strings at runtime, including content not known at build time
## Inline translation with `getGT()`
Use [`getGT()`](/docs/node/api/get-gt) when the string is only used in one place, or when the content depends on request-specific data:
```js title="routes/greeting.js"
import { getGT } from 'gt-node';
app.get('/api/greeting', async (req, res) => {
const gt = await getGT();
res.json({
message: gt('Hello, world!'),
});
});
```
### Variable interpolation
Pass variables as the second argument using `{name}` placeholders:
```js
const gt = await getGT();
gt('Welcome, {name}!', { name: user.displayName });
gt('You have {count} new messages.', { count: unreadCount });
gt('{city} weather: {temp}°F', { city: 'Tokyo', temp: 72 });
```
## Pre-registered strings with `msg()` / `getMessages()`
Use [`msg()`](/docs/node/api/get-messages) to register strings at module scope — outside of any request handler. Then use [`getMessages()`](/docs/node/api/get-messages) inside handlers to resolve them for the current locale:
```js title="messages.js"
import { msg } from 'gt-node';
export const GREETING = msg('Hello, world!');
export const WELCOME = msg('Welcome, {name}!');
export const NOT_FOUND = msg('Resource not found.');
export const UNAUTHORIZED = msg('You must be logged in.');
```
```js title="routes/api.js"
import { getMessages } from 'gt-node';
import { GREETING, WELCOME, NOT_FOUND } from './messages.js';
app.get('/api/greeting', async (req, res) => {
const m = await getMessages();
res.json({
greeting: m(GREETING),
welcome: m(WELCOME, { name: 'Alice' }),
});
});
app.use(async (req, res) => {
const m = await getMessages();
res.status(404).json({ error: m(NOT_FOUND) });
});
```
This approach is best when:
- The same string is used across multiple handlers
- Strings are shared constants (error messages, labels, enums)
- You want all translatable strings in one file for easy review
## On-demand translation with `tx()`
Use [`tx()`](/docs/node/api/strings/tx) when the content is not known at build time — for example, user-generated content or dynamic data that can't be pre-translated:
```js title="routes/translate.js"
import { tx } from 'gt-node';
app.post('/api/translate', async (req, res) => {
const translated = await tx(req.body.text);
res.json({ translated });
});
```
`tx` is async and performs translation on demand via a network request, so it's slower than build-time approaches. Use it only when `getGT()` or `msg()` can't cover the use case.
## When to use which
| Pattern | Best for |
|---------|----------|
| `getGT()` | One-off strings, request-specific content, strings that appear in one handler |
| `msg()` / `getMessages()` | Shared constants, error messages, enum labels, centralized string management |
| `tx()` | Dynamic or user-generated content not known at build time |
Both approaches produce identical translations. The difference is only in code organization — pick whichever fits your project structure.
## Using `$context` for disambiguation
Ambiguous strings can produce inaccurate translations. Add `$context` to guide the translator:
```js
// Inline
const gt = await getGT();
gt('Apple', { $context: 'the technology company' });
gt('Spring', { $context: 'the season, not a coil' });
// Pre-registered
const APPLE = msg('Apple', { $context: 'the fruit' });
const SPRING = msg('Spring', { $context: 'a metal coil' });
```
## Complete example
```js title="server.js"
import express from 'express';
import { initializeGT, withGT, getGT, msg, getMessages } from 'gt-node';
initializeGT({
defaultLocale: 'en',
locales: ['en', 'es', 'fr', 'ja'],
projectId: process.env.GT_PROJECT_ID,
});
// Pre-register shared strings
const ERRORS = {
notFound: msg('Resource not found.'),
unauthorized: msg('You must be logged in.'),
forbidden: msg('You do not have permission to access this resource.'),
};
const app = express();
app.use((req, res, next) => {
const locale = req.headers['accept-language']?.split(',')[0] || 'en';
withGT(locale, () => next());
});
// Inline translation
app.get('/api/dashboard', async (req, res) => {
const gt = await getGT();
res.json({
title: gt('Dashboard'),
subtitle: gt('Welcome back, {name}!', { name: req.user.name }),
});
});
// Pre-registered messages
app.use(async (req, res) => {
const m = await getMessages();
res.status(404).json({ error: m(ERRORS.notFound) });
});
app.listen(3000);
```
## Next steps
- [`getGT` API reference](/docs/node/api/get-gt)
- [`msg` & `getMessages` API reference](/docs/node/api/get-messages)
- [`tx` API reference](/docs/node/api/strings/tx) — runtime translation
- [Locale Detection & Middleware](/docs/node/guides/middleware) — how locale context works
# node: Node.js Quickstart
URL: https://generaltranslation.com/en-US/docs/node/tutorials/quickstart.mdx
---
title: Node.js Quickstart
description: Add multiple languages to your Node.js server in under 10 minutes
---
By the end of this guide, your Node.js server will respond with translated content based on the request's language, using either inline or pre-registered strings.
**Prerequisites:**
- A Node.js server (Express, Fastify, or similar)
- Node.js 18+
**Want automatic setup?** Run `npx gt@latest` to configure everything with the [Setup Wizard](/docs/cli/init). This guide covers manual setup.
---
## Step 1: Install the packages
`gt-node` is the library that powers translations in your server. `gt` is the CLI tool that prepares translations for production.
```bash
npm i gt-node
npm i -D gt
```
```bash
yarn add gt-node
yarn add --dev gt
```
```bash
bun add gt-node
bun add --dev gt
```
```bash
pnpm add gt-node
pnpm add --save-dev gt
```
---
## Step 2: Create a translation config file
Create a **`gt.config.json`** file in your project root. This tells the library which languages you support:
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["es", "fr", "ja"]
}
```
- **`defaultLocale`** — the language your server's strings are written in.
- **`locales`** — the languages you want to translate into. Pick any from the [supported locales list](/docs/platform/supported-locales).
---
## Step 3: Initialize General Translation
Call **`initializeGT`** once at the top of your server's entry file, before any translation functions are used:
```js title="server.js"
import { initializeGT } from 'gt-node';
initializeGT({
defaultLocale: 'en',
locales: ['en', 'es', 'fr', 'ja'],
projectId: process.env.GT_PROJECT_ID,
});
```
This configures the library with your supported languages and project credentials.
---
## Step 4: Set locale context per request
Each request needs to know which language to use. Use **`withGT`** to wrap your request handlers — it uses async local storage so translation functions automatically pick up the right locale:
```js title="server.js"
import { withGT } from 'gt-node';
app.use((req, res, next) => {
const locale = req.headers['accept-language']?.split(',')[0] || 'en';
withGT(locale, () => next());
});
```
---
## Step 5: Translate inline strings
For translating strings directly inside request handlers, use **`getGT`**:
```js title="server.js"
import { getGT } from 'gt-node';
app.get('/api/greeting', async (req, res) => {
const gt = await getGT();
res.json({
message: gt('Hello, world!'),
welcome: gt('Welcome, {name}!', { name: 'Alice' }),
});
});
```
`getGT` returns a translation function scoped to the current request's locale.
---
## Step 6: Pre-register constant strings (optional)
For strings defined outside request handlers — like error messages, enum labels, or constants — use **`msg`** to register them at module scope, then **`getMessages`** to resolve translations at runtime:
```js title="messages.js"
import { msg } from 'gt-node';
export const GREETING = msg('Hello, world!');
export const WELCOME = msg('Welcome, {name}!');
export const NOT_FOUND = msg('Resource not found.');
```
```js title="handler.js"
import { getMessages } from 'gt-node';
import { GREETING, WELCOME, NOT_FOUND } from './messages.js';
app.get('/api/status', async (req, res) => {
const m = await getMessages();
res.json({
greeting: m(GREETING),
welcome: m(WELCOME, { name: 'Alice' }),
});
});
app.use(async (req, res) => {
const m = await getMessages();
res.status(404).json({ error: m(NOT_FOUND) });
});
```
This pattern is useful when the same strings are used across multiple handlers.
---
## Step 7: Set up environment variables (optional)
To see translations in development, you need API keys from General Translation. These enable **on-demand translation** — your server translates content in real time as you develop.
Create a **`.env`** file:
```bash title=".env"
GT_API_KEY="your-api-key"
GT_PROJECT_ID="your-project-id"
```
Get your free keys at [dash.generaltranslation.com](https://dash.generaltranslation.com/signup) or by running:
```bash
npx gt auth
```
Never expose `GT_API_KEY` publicly or commit it to source control.
Yes. Without API keys, `gt-node` works as a standard i18n library. You won't get on-demand translation in development, but you can still:
- Provide your own translation files manually
- Use all translation functions (`getGT`, `msg`, `getMessages`, etc.)
- Run `npx gt generate` to create translation file templates, then translate them yourself
---
## Step 8: See it working
Start your server and test with different `Accept-Language` headers:
```bash
# Default (English)
curl http://localhost:3000/api/greeting
# Spanish
curl -H "Accept-Language: es" http://localhost:3000/api/greeting
# French
curl -H "Accept-Language: fr" http://localhost:3000/api/greeting
```
You should see translated responses for each language.
In development, translations happen on-demand — you may see a brief delay the first time a new language is requested. In production, translations are pre-generated and load instantly.
---
## Step 9: Full example
Here's a complete Express server with all the pieces together:
```js title="server.js"
import express from 'express';
import { initializeGT, withGT, getGT, msg, getMessages } from 'gt-node';
// Initialize GT before anything else
initializeGT({
defaultLocale: 'en',
locales: ['en', 'es', 'fr', 'ja'],
projectId: process.env.GT_PROJECT_ID,
});
// Pre-register constant strings
const NOT_FOUND = msg('Resource not found.');
const app = express();
// Set locale context for each request
app.use((req, res, next) => {
const locale = req.headers['accept-language']?.split(',')[0] || 'en';
withGT(locale, () => next());
});
// Inline translation
app.get('/api/greeting', async (req, res) => {
const gt = await getGT();
res.json({ message: gt('Hello, world!') });
});
// Pre-registered message translation
app.use(async (req, res) => {
const m = await getMessages();
res.status(404).json({ error: m(NOT_FOUND) });
});
app.listen(3000, () => console.log('Server running on port 3000'));
```
---
## Step 10: Deploy to production
In production, translations are pre-generated at build time (no real-time API calls). Add the translate command to your build script:
```json title="package.json"
{
"scripts": {
"build": "npx gt translate && "
}
}
```
Set your **production** environment variables in your hosting provider:
```bash
GT_PROJECT_ID=your-project-id
GT_API_KEY=gtx-api-your-production-key
```
Never publicly expose your `GT_API_KEY`.
That's it — your server is now multilingual. 🎉
---
## Troubleshooting
This is expected. In development, translations happen on-demand (your content is translated in real time via the API). This delay **does not exist in production** — all translations are pre-generated by `npx gt translate`.
Ambiguous text can lead to inaccurate translations. For example, "apple" could mean the fruit or the company. Add a `$context` option to help:
```js
gt('Apple', { $context: 'the technology company' });
```
Both `getGT()` and `msg()` support the `$context` option.
---
## Next steps
- [**`initializeGT`**](/docs/node/api/initialize-gt) — Full configuration options
- [**`withGT`**](/docs/node/api/with-gt) — Locale context for requests
- [**`getGT`**](/docs/node/api/get-gt) — Inline string translation
- [**`msg` & `getMessages`**](/docs/node/api/get-messages) — Pre-registered message translation
- [**CLI**](/docs/cli/translate) — Translation workflow reference
# General Translation Platform: Apply Glossary
URL: https://generaltranslation.com/en-US/docs/platform/context/apply-glossary.mdx
---
title: Apply Glossary
description: Push glossary changes into existing translated files
---
When you update glossary terms, existing translations do not change automatically. **Apply** updates only files that contain selected terms, which makes it more targeted than retranslating every file.

**Note:** Apply is available from the project Context page, not the organization context library. The project needs at least one connected branch for Apply to appear.
## Apply vs other actions
| Action | What it does |
|--------|--------------|
| **Translate** (glossary toolbar) | Uses AI to generate translations for glossary term definitions and locale columns |
| **Apply** (glossary toolbar) | Updates existing project files that contain the selected glossary terms |
| **Retranslate** (Translations page) | Regenerates an entire translated file |
Use **Translate** when you've added new terms and need their per-locale glossary entries filled in. Use **Apply** when terms already exist and you want existing translated content to pick up the changes.
## How to apply glossary changes
1. Open **Context** in the project sidebar
2. Select a context group and open the **Glossary** tab
3. Make your glossary edits and save
4. Click **Apply** in the toolbar
5. In the dialog:
- Select the glossary terms to apply
- Choose target locales to update
- Choose branches (if your project has multiple)
6. Click **Apply** to start background retranslation
Only files containing the selected terms are updated. If no files contain the selected terms, the dialog reports that no matches were found.
## Progress and completion
Apply runs as background jobs. The dialog shows progress by file and locale count. You can close the dialog and navigate away while jobs continue.
When complete, affected translations appear updated in the Translations page. Use [Locadex](/docs/locadex) to sync changes back to your repository.
## Next steps
- [Glossary](/docs/platform/context/glossary)
- [Retranslate content](/docs/platform/translations/retranslate)
- [Locadex Agent](/docs/locadex)
# General Translation Platform: Directives
URL: https://generaltranslation.com/en-US/docs/platform/context/directives.mdx
---
title: Directives
description: Provide instructions that guide AI translation tone and style
---
Directives are instructions that guide how the AI translates your content. Use them for tone, audience, formality, regional conventions, formatting rules, and other translation guidance that does not belong in the glossary.

## Global vs locale-specific directives
Each directive has:
- **Name**: a short label, such as "Tone and style" or "Formality"
- **Description**: optional context about what the directive covers
- **Value**: the instruction the AI should follow
- **Locale**: either **All locales** or one target locale
**Tip:** Use **All locales** for project-wide guidance like tone, audience, and brand voice. Use locale-specific directives when one language needs different treatment.
## Example directives
| Name | Locale | Value |
|------|--------|-------|
| Tone and style | All locales | Professional and concise. Use active voice. Avoid jargon unless defined in the glossary. |
| Target audience | All locales | Enterprise software developers. |
| Formality | German | Use formal "Sie". |
## Writing effective directives
Be specific and direct:
```
Good: "Professional and concise. Use active voice. Avoid jargon unless defined in the glossary."
Too vague: "Make it sound nice."
```
## How directives are applied
Directives from all assigned context groups are considered when translating. If multiple groups provide overlapping guidance, the project's [context group priority](/docs/platform/context#priority) determines which group has precedence.
Changes to directives do not automatically update existing translations. [Retranslate](/docs/platform/translations/retranslate) affected files to apply updated guidance.
## Next steps
- [Context groups](/docs/platform/context)
- [Glossary](/docs/platform/context/glossary)
- [Retranslate content](/docs/platform/translations/retranslate)
# General Translation Platform: Glossary
URL: https://generaltranslation.com/en-US/docs/platform/context/glossary.mdx
---
title: Glossary
description: Define terms that must stay consistent across translations
---
The glossary defines terms that should stay consistent across translations. Use it for product names, feature names, technical terms, and domain-specific vocabulary.

## When to use the glossary
- Product and brand names that should not be translated
- Feature names that need a specific translation
- Technical terms that need consistent wording
- Phrases where the definition matters as much as the source text
## Adding terms
1. Open a context group and select the **Glossary** tab
2. Click **Add term**
3. Enter the term as it appears in your source content
4. Add a definition so the AI understands the meaning
5. Add locale-specific translations when a term must use exact wording
## Managing terms
- **Search** finds existing terms quickly
- **Filter** shows all entries, user-defined terms, or auto-detected terms
- **Locale columns** let you edit per-language translations
- **Inline editing** updates terms, definitions, and translations directly in the table
- **Bulk delete** removes selected terms
## Auto-detected terms
The dashboard can show auto-detected glossary candidates from your project content. Review these terms before relying on them for translation guidance.
## Translate vs Apply
| Button | What it does |
|--------|--------------|
| **Translate** | Uses AI to fill empty glossary translations for selected locale columns |
| **Apply** | Updates existing project files that contain selected glossary terms |
Use **Translate** after adding terms that need per-locale glossary entries. Use **Apply** when existing translated files need to pick up glossary changes. See [Apply glossary](/docs/platform/context/apply-glossary).
## Importing terms
Use **Import** on a context group to bulk-add glossary terms and directives. Import fills empty fields and preserves existing values.
## Next steps
- [Context groups](/docs/platform/context)
- [Directives](/docs/platform/context/directives)
- [Apply glossary](/docs/platform/context/apply-glossary)
# General Translation Platform: Context Groups
URL: https://generaltranslation.com/en-US/docs/platform/context.mdx
---
title: Context Groups
description: Organize glossary and directives into shareable groups
---
Context groups define the terminology and instructions used when AI generates translations. Each group contains a [glossary](/docs/platform/context/glossary) and [directives](/docs/platform/context/directives). Groups live in an organization and can be assigned to one or more projects.
## Organization vs project scope
| Scope | What you see | What you can do |
|-------|--------------|-----------------|
| **Organization -> Context** | The full group library | Create, rename, delete, import, export, and edit groups |
| **Project -> Context** | Groups assigned to the current project | Assign groups, create a new assigned group, set priority, and edit group content |
**Note:** Editing a group from a project updates the shared organization-level group. If that group is assigned to other projects, your changes apply there too.
## Creating a group
At the organization level:
1. Open **Context** in the org sidebar
2. Click **Create group**
3. Enter a name and confirm
From a project:
1. Open **Context** in the project sidebar
2. Click **Create group**
3. Enter a name and confirm
When you create a group from a project, the group is created in the organization and assigned to the current project.
## Assigning groups to a project
Projects do not inherit every organization group automatically.
1. Open **Context** in the project sidebar
2. Click **Assign existing groups**
3. Select one or more groups from the org library
4. Click **Assign**
Assigned groups apply their glossary and directives whenever the project is translated, retranslated, or processed by Locadex.
## Priority
When a project has multiple assigned groups, priority determines which guidance wins when groups overlap.
- The top group has the highest priority
- Reorder groups from the project Context page
- If the same glossary term appears in multiple groups, the higher-priority group is used
- Newly generated or imported terms are saved to the highest-priority group
## Import and export
Use import and export to move context between tools or seed a group from an existing terminology list.
- **Import** fills empty glossary and directive fields from a supported file
- **Export** downloads the group's glossary and directives
## How context affects translations
Context is applied whenever the AI generates translations, including initial translation, [retranslation](/docs/platform/translations/retranslate), [Apply glossary](/docs/platform/context/apply-glossary), and Locadex processing.
Changes to context do not automatically rewrite every existing translation. Use Retranslate or Apply glossary to propagate changes into existing files.
## Next steps
- [Glossary](/docs/platform/context/glossary)
- [Directives](/docs/platform/context/directives)
- [Apply glossary](/docs/platform/context/apply-glossary)
# General Translation Platform: Roles & Permissions
URL: https://generaltranslation.com/en-US/docs/platform/orgs/roles.mdx
---
title: Roles & Permissions
description: Understand the default roles and permissions available in your organization
---
Every member of an organization is assigned a **role** that determines what they can access and modify. Roles are assigned when a member is invited or can be changed later by an Owner or Admin.
## Organization roles
When an organization is created, five default roles are set up automatically:
| Role | Description |
| ------------- | --------------------------------------------------------------------------------------------------------------------- |
| **Owner** | Full access to everything. Can delete the organization and transfer ownership. Bypasses all permission checks. |
| **Admin** | Full access to all organization and project settings, members, billing, and translations. |
| **Developer** | Technical access to projects—API keys, GitHub integration, Locadex, and usage data. Cannot manage members or billing. |
| **Editor** | Can read, edit, and review translations. No access to settings, members, or billing. |
| **Member** | Can view the organization but has no specific permissions. Useful as a base role with additional per-user overrides. |
## Enterprise roles
Enterprise accounts have an additional layer of roles for managing multiple organizations. For details on enterprise roles and permissions, [contact us](https://generaltranslation.com/contact).
## Permissions reference
Permissions are grouped into categories. The table below shows which default roles have access to each permission.
### Organization permissions
| Permission | Owner | Admin | Developer | Editor | Member |
| ------------------------ | :---: | :---: | :-------: | :----: | :----: |
| Update org settings | ✓ | ✓ | | | |
| Manage projects & plan | ✓ | ✓ | | | |
| Manage members | ✓ | ✓ | | | |
| View usage | ✓ | ✓ | ✓ | | |
| Read GitHub integration | ✓ | ✓ | ✓ | | |
| Write GitHub integration | ✓ | ✓ | ✓ | | |
### Project permissions
| Permission | Owner | Admin | Developer | Editor | Member |
| ------------------------ | :---: | :---: | :-------: | :----: | :----: |
| Update project settings | ✓ | ✓ | | | |
| Read API keys | ✓ | ✓ | ✓ | | |
| Create & delete API keys | ✓ | ✓ | ✓ | | |
| Read project context | ✓ | ✓ | | | |
| Write project context | ✓ | ✓ | | | |
| Read Locadex settings | ✓ | ✓ | ✓ | | |
| Write Locadex settings | ✓ | ✓ | ✓ | | |
### Translation permissions
| Permission | Owner | Admin | Developer | Editor | Member |
| ----------------------------- | :---: | :---: | :-------: | :----: | :----: |
| Read translations | ✓ | ✓ | | ✓ | |
| Edit translations | ✓ | ✓ | | ✓ | |
| Review & approve translations | ✓ | ✓ | | ✓ | |
### Roles & billing permissions
| Permission | Owner | Admin | Developer | Editor | Member |
| ----------------------- | :---: | :---: | :-------: | :----: | :----: |
| View roles | ✓ | ✓ | | | |
| Create & delete roles | ✓ | ✓ | | | |
| Assign roles to members | ✓ | ✓ | | | |
| View billing | ✓ | ✓ | | | |
| Update billing | ✓ | ✓ | | | |
## Permission inheritance
Permissions flow downward through the hierarchy:
**Enterprise → Organization → Project**
If a user has a permission at the enterprise level, they automatically have it for all organizations and projects within that enterprise. Similarly, organization-level permissions apply to all projects in that organization.
# General Translation Platform: Webhooks
URL: https://generaltranslation.com/en-US/docs/platform/orgs/webhooks.mdx
---
title: Webhooks
description: Receive real-time notifications when events happen in your organization
---
Webhooks let your application receive HTTP POST requests when events happen in your organization, such as a translated file completing or a translation job finishing.
Webhooks are available on the **Team plan** and above.
## Setting up a webhook
1. Go to **Organization Settings → Webhooks**
2. Click **Create Webhook**
3. Enter the endpoint URL where you want to receive events (must be HTTPS)
4. Select the event types you want to subscribe to
5. Click **Create**
After creating the endpoint, navigate to the webhook detail page and copy the signing secret. You'll use this secret to verify that incoming requests are from General Translation.
You can create up to **5 webhook endpoints** per organization.
## Event types
| Event | Description |
| --------------------------- | ---------------------------------------------------------------------------------- |
| `translated_file.completed` | Fires when a translated file is completed and ready to download |
| `translated_file.edited` | Fires when a translated file is manually edited by a user in the translation editor |
| `translation_job.completed` | Fires when a translation job completes |
Each endpoint can subscribe to one or more event types. You can update your subscriptions at any time from the webhook detail page.
## Payload format
Every webhook delivery is an HTTP POST with a JSON body:
```json
{
"id": "evt_xxx",
"type": "translated_file.completed",
"created_at": "2026-04-30T12:00:00.000Z",
"api_version": "2026-03-06.v1",
"data": {
"object": {
"id": "file_xxx",
"org_id": "org_xxx",
"project_id": "project_xxx",
"branch_id": "branch_xxx",
"source_file_id": "src_xxx",
"file_id": "file_xxx",
"version_id": "ver_xxx",
"locale": "fr",
"file_format": "json",
"data_format": null,
"completed_at": "2026-04-30T12:00:00.000Z"
}
}
}
```
The top-level `id` is a stable event identifier you can use to deduplicate deliveries on your end.
## Verifying signatures
Every webhook request includes three headers for signature verification:
| Header | Description |
| ------------------- | -------------------------------------------------- |
| `webhook-id` | The event ID (`evt_xxx`) |
| `webhook-timestamp` | Unix timestamp (seconds) when the request was sent |
| `webhook-signature` | `v1,` signature |
The signature follows the [Standard Webhooks](https://www.standardwebhooks.com/) convention. To verify:
1. Concatenate: `{webhook-id}.{webhook-timestamp}.{raw request body}`
2. Compute HMAC-SHA256 using your signing secret (base64-decode the secret after removing the `whsec_` prefix)
3. Base64-encode the result and compare against the signature value (after the `v1,` prefix)
4. Check that the timestamp is within 5 minutes of the current time to prevent replay attacks
### Example (Node.js)
```js
import crypto from "crypto";
function verifyWebhook(payload, headers, secret) {
const msgId = headers["webhook-id"];
const timestamp = headers["webhook-timestamp"];
const signature = headers["webhook-signature"];
// Check timestamp freshness (5 minute tolerance)
const now = Math.floor(Date.now() / 1000);
if (Math.abs(now - parseInt(timestamp)) > 300) {
throw new Error("Timestamp too old");
}
// Compute expected signature
const signingKey = Buffer.from(secret.replace("whsec_", ""), "base64");
const signedContent = `${msgId}.${timestamp}.${payload}`;
const expected = crypto
.createHmac("sha256", signingKey)
.update(signedContent)
.digest("base64");
// Compare (constant-time)
const received = signature.split(",")[1];
if (!crypto.timingSafeEqual(Buffer.from(expected), Buffer.from(received))) {
throw new Error("Invalid signature");
}
return JSON.parse(payload);
}
```
You can also use the [Standard Webhooks](https://www.standardwebhooks.com/) library for your language, which handles verification automatically.
## Retries and delivery
Webhooks use **at-least-once delivery**. If your endpoint doesn't return a `2xx` response within 10 seconds, the delivery is retried with exponential backoff for up to **10 attempts**.
You can also manually retry a failed delivery from the webhook detail page in the dashboard.
### Handling duplicates
Because delivery is at-least-once, your endpoint may receive the same event more than once. Use the `id` field in the payload to deduplicate:
```js
app.post("/webhooks/gt", (req, res) => {
const eventId = req.body.id;
if (alreadyProcessed(eventId)) {
return res.status(200).send("OK");
}
// Process the event...
markProcessed(eventId);
res.status(200).send("OK");
});
```
## Managing endpoints
From the webhook detail page, you can:
- **Enable/disable** an endpoint without deleting it
- **Update** the subscribed event types
- **View delivery history** and inspect individual delivery attempts
- **Retry** a failed delivery
- **Reveal** the signing secret (for re-copying)
- **Delete** the endpoint
## Best practices
- **Respond quickly** — return a `2xx` response as fast as possible, then process the event asynchronously. Long-running handlers risk timeouts.
- **Verify signatures** — always validate the `webhook-signature` header before trusting the payload.
- **Handle duplicates** — store processed event IDs and skip duplicates.
- **Use HTTPS** — webhook endpoints must use HTTPS in production.
- **Monitor failures** — check your delivery history periodically for persistent failures that may indicate an issue with your endpoint.
## Permissions
Managing webhook endpoints requires the `org:webhooks:write` permission. Viewing delivery history requires `org:webhooks:read`. By default, the **Owner** and **Admin** roles have both permissions. See [Roles & Permissions](/docs/platform/orgs/roles) for details.
# General Translation Platform: API Keys
URL: https://generaltranslation.com/en-US/docs/platform/projects/api-keys.mdx
---
title: API Keys
description: Manage authentication keys for your application
---
API keys authenticate your application with GT services. You'll find the API Keys page in the project sidebar.

## Production keys
Production API keys are strings starting with `gtx-api-`. Use these in your deployed application.
### Creating a production key
1. Click **Create API Key**
2. Enter a name for the key (e.g., "Production", "Web App")
3. Copy the full key immediately—you won't be able to see it again
4. Store it securely (environment variables, secrets manager, etc.)
### Managing keys
- **Preview**: Shows a truncated version of the key for identification
- **Created At**: When the key was generated
- **Last Used**: When the key was last used (helps identify stale keys)
- **Delete**: Revoke a key you no longer need
## Development keys
Development keys are for local development and preview environments. They start with `gtx-dev-` and should never be used in production.
| | Production | Development |
|---|-----------|-------------|
| Prefix | `gtx-api-` | `gtx-dev-` |
| Use case | Deployed apps | Local dev, previews |
| Translations | Published content | Preview translations |
Development keys let you test translations before they're published, without affecting your live application.
## Security best practices
- **Never commit keys to source control**—use environment variables
- **Rotate keys periodically**—delete old keys and create new ones
- **Use descriptive names**—makes it easier to identify and manage keys
- **Revoke unused keys**—if a key hasn't been used in months, delete it
- **Separate environments**—use different keys for staging and production
# General Translation Platform: Settings
URL: https://generaltranslation.com/en-US/docs/platform/projects/settings.mdx
---
title: Settings
description: Configure project details and project-level behavior
---
Use project Settings to manage the project name, copy the project ID, and configure project-level behavior.
## General settings
Update the project display name from the general settings card. This changes how the project appears in the dashboard.
## Project ID
The project ID is read-only and can be copied from Settings. Use it in SDK, CLI, and CI configuration when a workflow needs to target a specific project.
```bash
GT_PROJECT_ID=...
```
## CDN
Enable the CDN setting when your application should load translations from the General Translation CDN. Disable it when your project should not publish translations through CDN delivery.
## AI Context
Enable AI Context when generated translations should use contextual information to improve translation quality. This setting works alongside the project's assigned [context groups](/docs/platform/context).
## Danger zone
Project Settings includes destructive actions such as deleting the project. Deleting a project removes its dashboard configuration and translation data.
## Next steps
- [Context groups](/docs/platform/context)
- [API keys](/docs/platform/api-keys)
- [Locadex Agent](/docs/locadex)
# General Translation Platform: Annotations
URL: https://generaltranslation.com/en-US/docs/platform/translations/annotations.mdx
---
title: Annotations
description: Label, note, and discuss translation entries
---
Annotations let you add labels, notes, and threaded comments to translation entries without changing the translated text. Use them to run review workflows, flag issues, and coordinate with your team.

## Annotation types
Each entry and locale can have three annotation types:
| Type | Purpose |
|------|---------|
| **Labels** | Colored tags for categorizing entries, such as "Needs review", "Approved", or "Legal" |
| **Notes** | A free-text note attached to the entry, useful for translator guidance or internal context |
| **Comments** | Threaded discussions with replies, resolve, and reopen |
Annotations are locale-scoped. An entry's Spanish translation can have different labels, notes, and comments than its French translation. Source content can also have its own annotation scope when source annotations are enabled.
## Opening the annotation panel
Click the annotation indicator on a translation row or cell to open the panel. The panel opens for the selected entry and locale. You can also use the quick-label popover to add labels without opening the full panel.
## Labels
Labels are project-wide. You define a catalog of labels with names and colors, then apply those labels to entries and locales.
- **Create labels** from the annotation panel or the quick-label popover
- **Toggle labels** on and off for the current entry and locale
- **Edit or archive** labels from the label editor
- **Filter by label** using the annotation filter in the translation header
## Notes
Add one note per entry and locale. Notes are plain text. Use them for translator instructions, context the AI might miss, or internal reminders.
## Comments
Comments support threaded discussions:
1. Add a comment from the annotation panel
2. Team members can reply to create a thread
3. **Resolve** a thread when the discussion is complete
4. **Reopen** a resolved thread if the issue comes back
Resolved threads collapse into a separate section so active discussions stay visible.
## Bulk label management
Select rows with the checkboxes, then click **Manage labels** to apply or remove labels across selected entries. When the view supports multiple locales, choose which locale scopes the bulk change should affect.
## Multi-locale view
When viewing multiple locales at once, annotation indicators appear per locale. Opening an indicator opens the panel for that entry and locale, so you can create or edit annotations without switching back to a single-locale table.
## Filtering by label
Use the annotation filter in the translation header to show entries with specific labels. This is useful for review workflows like surfacing everything marked "Needs review."
## Next steps
- [Editing translations](/docs/platform/translations)
- [Retranslate content](/docs/platform/translations/retranslate)
# General Translation Platform: Editing translations
URL: https://generaltranslation.com/en-US/docs/platform/translations.mdx
---
title: Editing translations
description: Browse, view, and edit translated content
---
Use the Translations page to review and edit translated content for a project. The page supports file-based content and component-based content, with the same core editing tools in both views.
## Files vs components
| View | Best for |
|------|----------|
| **Files** | Markdown, JSON, gettext, and other file-based content |
| **Components** | React/JSX projects where strings live in UI components |
Switch between tabs at the top of the page. Both views support locale switching, inline editing, source visibility, search, downloads, and annotation filters.

## Working with translations
**Browse content**: Use the file tree or component list to select content. Search filters the current view by file name, component name, key, source text, or translated text.
**Choose a branch**: Use the branch selector when your project has repository-backed translations on multiple branches.
**Choose locales**: Select one locale for a focused editor, or select multiple locales to compare translations side by side.
**Edit inline**: Click a translation cell to edit it. For supported raw formats, toggle **Raw** to edit the underlying file content in a code editor.
**Use file tools**: Open history, compare against a previous version, download translated output, show or hide source content, and filter by [annotation labels](/docs/platform/translations/annotations).
## Version history
Open history from a file to inspect previous translation versions. Use history when you need to compare a manual edit, restore a prior state, or confirm when a translated file changed.
## Multi-locale view
Select multiple locales to compare translations in one table. Annotation indicators appear inside each locale cell. Click an indicator to open the annotation panel for that entry and locale.
## Project search
Press `⌘K` on macOS or `Ctrl+K` on Windows from any project page to search across files and components. Results link directly to the matching entry.
## Next steps
- [Annotations](/docs/platform/translations/annotations)
- [Retranslate content](/docs/platform/translations/retranslate)
- [Context groups](/docs/platform/context)
# General Translation Platform: Retranslating content
URL: https://generaltranslation.com/en-US/docs/platform/translations/retranslate.mdx
---
title: Retranslating content
description: Regenerate translations with updated source or context
---
Use **Retranslate** when a translated file needs a new AI pass. Retranslation is useful after source changes, context updates, or manual review when you want the file regenerated with the latest glossary and directives.
## When to retranslate
- Source content changed
- [Context](/docs/platform/context) changed
- A file needs a full quality pass
- A branch needs translations regenerated after a repository update
## How retranslation works
1. Open the file in the Translations page
2. Confirm that the branch and target locale are correct
3. Click **Retranslate**
4. Wait for the background job to finish
5. Review the regenerated translation
Retranslation runs in the background. You can navigate away while the job continues; the file updates when the job completes.
## Retranslate vs Apply glossary
Retranslate regenerates an entire file. If you only need existing translations to pick up selected glossary terms, use [Apply glossary](/docs/platform/context/apply-glossary) from the project Context page instead. Apply glossary targets only files that contain the selected terms.
## Sync changes to your repository
After retranslating, a banner appears showing how many files have pending changes. Click **Run Agent** to open Locadex and sync everything back to your repository.
If you are retranslating multiple files, finish the batch before running Locadex so the changes can be grouped into one pull request.
## Next steps
- [Editing translations](/docs/platform/translations)
- [Apply glossary](/docs/platform/context/apply-glossary)
- [Locadex Agent](/docs/locadex)
# python: declare_var
URL: https://generaltranslation.com/en-US/docs/python/api/declare-var.mdx
---
title: declare_var
description: API reference for the declare_var function
---
## Overview
`declare_var` wraps a dynamic value with a GT variable marker so that translation engines can preserve the variable in translated output.
```python
from gt_flask import declare_var # or from gt_fastapi import declare_var
greeting = declare_var("Alice", name="user")
```
## Reference
### Parameters
### Returns
`str` — an ICU select construct that wraps the value as a GT variable marker.
---
## Notes
- Use `declare_var` for values that change at runtime (e.g., user names, counts).
- See also [`derive`](/docs/python/api/derive) for values known at build time.
- Use [`decode_vars`](/docs/python/api/decode-vars) to extract the variables back from a marked string.
# python: decode_vars
URL: https://generaltranslation.com/en-US/docs/python/api/decode-vars.mdx
---
title: decode_vars
description: API reference for the decode_vars function
---
## Overview
`decode_vars` replaces GT variable markers in a string with their embedded values.
```python
from gt_flask import decode_vars # or from gt_fastapi import decode_vars
result = decode_vars(marked_string)
```
## Reference
### Parameters
### Returns
`str` — the string with GT variable markers replaced by their original values.
---
## Notes
- Typically used with strings that were built using [`declare_var`](/docs/python/api/declare-var) or [`derive`](/docs/python/api/derive).
# python: derive
URL: https://generaltranslation.com/en-US/docs/python/api/derive.mdx
---
title: derive
description: API reference for the derive function
---
## Overview
`derive` marks content as statically analyzable so that the GT CLI can extract all possible translation entries at build time.
It is an **identity function** — it returns exactly what you pass in. Its purpose is as a marker for static analysis.
```python
from gt_flask import derive, t # or from gt_fastapi
message = t(f"The {derive('boy' if gender == 'male' else 'girl')} is playing.")
```
## Reference
### Parameters
### Returns
Returns `content` unchanged. The function is an identity — its purpose is as a marker for the CLI.
---
## Notes
- All possible outcomes must be statically analyzable at build time
- Dynamic content (user input, API data) inside `derive` should be wrapped with [`declare_var`](/docs/python/api/declare-var)
- Use [`decode_vars`](/docs/python/api/decode-vars) to extract original values from declared variables
- See the [derive tutorial](/docs/python/tutorials/derive) for detailed examples and usage patterns
# python: get_default_locale
URL: https://generaltranslation.com/en-US/docs/python/api/get-default-locale.mdx
---
title: get_default_locale
description: API reference for the get_default_locale function
---
## Overview
Returns the default (source) locale configured via [`initialize_gt`](/docs/python/api/initialize-gt) or `gt.config.json`.
```python
from gt_flask import get_default_locale # or from gt_fastapi import get_default_locale
default = get_default_locale() # e.g., "en"
```
## Reference
### Returns
`str` — the default locale code.
# python: get_locale
URL: https://generaltranslation.com/en-US/docs/python/api/get-locale.mdx
---
title: get_locale
description: API reference for the get_locale function
---
## Overview
Returns the current locale as set by [`initialize_gt`](/docs/python/api/initialize-gt) middleware.
```python
from gt_flask import get_locale # or from gt_fastapi import get_locale
locale = get_locale() # e.g., "es"
```
## Reference
### Returns
`str` — the current locale code.
# python: get_locales
URL: https://generaltranslation.com/en-US/docs/python/api/get-locales.mdx
---
title: get_locales
description: API reference for the get_locales function
---
## Overview
Returns the list of supported locales configured via [`initialize_gt`](/docs/python/api/initialize-gt) or `gt.config.json`.
```python
from gt_flask import get_locales # or from gt_fastapi import get_locales
locales = get_locales() # e.g., ["en", "es", "fr"]
```
## Reference
### Returns
`list[str]` — the list of supported locale codes.
# python: initialize_gt
URL: https://generaltranslation.com/en-US/docs/python/api/initialize-gt.mdx
---
title: initialize_gt
description: API reference for the initialize_gt setup function
---
## Overview
The `initialize_gt` function configures General Translation for a Flask or FastAPI app.
It must be called once before any translation functions are used.
Settings are automatically loaded from a `gt.config.json` file in the current working directory.
Any keyword arguments override the config file values.
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
initialize_gt(app)
```
```python
from fastapi import FastAPI
from gt_fastapi import initialize_gt
app = FastAPI()
initialize_gt(app)
```
## Reference
### Parameters
str',
optional: true,
description: 'Custom locale detection callback. Defaults to parsing the Accept-Language header.',
},
"load_translations?": {
type: '(locale: str) -> dict[str, str]',
optional: true,
description: 'Custom function to load translations for a locale.',
},
"eager_loading?": {
type: 'bool',
optional: true,
default: 'True',
description: 'Load all translations at startup.',
},
"config_path?": {
type: 'str',
optional: true,
description: 'Path to a gt.config.json file. Defaults to "gt.config.json" in the CWD.',
},
"load_config?": {
type: '(path: str | None) -> GTConfig',
optional: true,
description: 'Custom config loader replacing the default.',
},
}}
/>
### Returns
`I18nManager` — the configured translation manager instance.
---
## Config file
Create a `gt.config.json` in your project root. All fields are optional:
```json title="gt.config.json"
{
"projectId": "your-project-id",
"defaultLocale": "en",
"locales": ["es", "fr"],
"cacheUrl": "https://custom-cache.example.com"
}
```
Settings from `gt.config.json` are used as defaults. Any keyword arguments passed to `initialize_gt` take precedence.
---
## Examples
### Minimal setup (with config file)
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
initialize_gt(app)
```
### With custom translation loader
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
def load_translations(locale: str) -> dict[str, str]:
# Load translations from your own source
...
initialize_gt(app, load_translations=load_translations)
```
### With custom locale detection
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
def get_locale(request):
return request.args.get("lang", "en")
initialize_gt(app, get_locale=get_locale)
```
---
## Notes
- `initialize_gt` must be called **once** before using `t` or any other translation function.
- On Flask, it registers a `before_request` hook for locale detection.
- On FastAPI, it registers middleware for locale detection and wraps the app lifespan for eager loading.
# python: t_fallback
URL: https://generaltranslation.com/en-US/docs/python/api/t-fallback.mdx
---
title: t_fallback
description: API reference for the t_fallback interpolation function
---
## Overview
`t_fallback` interpolates variables into a message string **without** performing a translation lookup.
Useful for strings that should be interpolated but not translated (e.g., user-facing defaults).
```python
from gt_i18n import t_fallback
message = t_fallback("Hello, {name}!", name="World")
```
## Reference
### Parameters
### Returns
`str` — the interpolated string.
---
## Examples
```python
from gt_i18n import t_fallback
# Simple interpolation
t_fallback("Welcome, {name}!", name="Alice")
# → "Welcome, Alice!"
```
---
## Notes
- Unlike [`t`](/docs/python/api/t), `t_fallback` never looks up translations — it only interpolates.
- Useful for fallback messages or strings in the default locale that don't need translation.
# python: t
URL: https://generaltranslation.com/en-US/docs/python/api/t.mdx
---
title: t
description: API reference for the t translation function
---
## Overview
The `t` function translates and interpolates an ICU MessageFormat string.
It looks up the current locale, finds a cached translation by hash, and interpolates variables.
If no translation is found, it falls back to the source string.
```python
from gt_flask import t # or from gt_fastapi import t
message = t("Hello, {name}!", name="World")
```
## Reference
### Parameters
### GT options (passed via `**kwargs`)
| Option | Type | Description |
| ------ | ---- | ----------- |
| `_context` | `str` | Additional context to disambiguate translations with the same source text. |
| `_id` | `str` | Custom identifier for the translation entry. |
| `_max_chars` | `int` | Maximum character length for the output. |
### Returns
`str` — the translated and interpolated string.
---
## Examples
### Simple translation
```python
t("Hello, world!")
```
### With variables
```python
t("Hello, {name}!", name="Alice")
```
### With context
```python
t("Bank", _context="financial institution")
t("Bank", _context="river bank")
```
### With f-strings and `declare_var`
Python f-strings work naturally with `t` — just wrap your variables with [`declare_var`](/docs/python/api/declare-var):
```python
from gt_flask import t, declare_var
# Before i18n:
message = f"{name} goes home"
# After i18n — just wrap with t() and declare_var():
message = t(f"{declare_var(name, name='name')} goes home")
```
### With character limit
```python
t("This is a very long message that might need truncation", _max_chars=20)
```
---
## Notes
- `t` requires [`initialize_gt`](/docs/python/api/initialize-gt) to be called first.
- If the current locale matches the default locale, no translation lookup is performed — only interpolation.
- Variables are interpolated using ICU MessageFormat syntax (e.g., `{name}`, `{count, plural, one {# item} other {# items}}`).
# python: Local Translation Storage
URL: https://generaltranslation.com/en-US/docs/python/guides/local-tx.mdx
---
title: Local Translation Storage
description: Store translations locally instead of fetching from a CDN
---
## What are local translations?
By default, GT's Python libraries fetch translations from the General Translation CDN at runtime. With local translations, you bundle translation files with your app — no external network requests needed.
**Default behavior:** GT uses CDN storage by default. Only switch to local storage if you need the specific benefits it provides.
## Trade-offs
### Benefits of local translations
- **Faster responses**: No network round-trips to fetch translations
- **No reliance on external services**: Your app works independently of CDN availability
- **Works offline**: Translations are part of your deployment
### Drawbacks of local translations
- **Increased deployment size**: Every supported locale adds translation files
- **Redeploy to update**: Changing a translation requires a new deployment
## Setup
### Step 1: Configure the CLI
Install the GT CLI and configure it for local storage:
```bash
pip install gtx-cli
gt configure
```
When prompted:
- **Save to CDN?** Select "No"
- **Translation directory:** Enter `./translations`
### Step 2: Generate translations
```bash
gt translate
```
This creates JSON files in your `translations/` directory — one per locale.
### Step 3: Load translations in your app
Point your app at the local translation files:
```python
import json
from pathlib import Path
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
def load_translations(locale: str):
path = Path('translations') / f'{locale}.json'
if path.exists():
return json.loads(path.read_text())
return {}
initialize_gt(
app,
default_locale='en',
locales=['es', 'fr', 'ja'],
load_translations=load_translations,
)
```
```python
import json
from pathlib import Path
from fastapi import FastAPI
from gt_fastapi import initialize_gt
app = FastAPI()
def load_translations(locale: str):
path = Path('translations') / f'{locale}.json'
if path.exists():
return json.loads(path.read_text())
return {}
initialize_gt(
app,
default_locale='en',
locales=['es', 'fr', 'ja'],
load_translations=load_translations,
)
```
## Build integration
Generate translations as part of your deployment pipeline:
```yaml title=".github/workflows/deploy.yml"
- name: Generate Translations
run: gt translate
- name: Deploy
run:
```
Or in a `Makefile`:
```makefile
deploy:
gt translate
```
Always generate translations before deploying. If translation files are missing, `t()` falls back to the original string in your `default_locale`.
## Next steps
- [CLI `translate` command](/docs/cli/translate) — translation generation reference
- [String Translation Patterns](/docs/python/guides/strings) — how to translate content
- [Locale Detection & Middleware](/docs/python/guides/middleware) — how locale context works
# python: Locale Detection & Middleware
URL: https://generaltranslation.com/en-US/docs/python/guides/middleware.mdx
---
title: Locale Detection & Middleware
description: How locale detection works in Flask and FastAPI, and how to customize it
---
GT's Python middleware automatically detects the user's locale on every request and makes it available to [`t()`](/docs/python/api/t) and [`get_locale()`](/docs/python/api/get-locale). This guide covers how detection works and advanced patterns for customization.
For a basic introduction to custom locale detection, see the [custom locale detection tutorial](/docs/python/tutorials/custom-locale-detection). This guide expands on those patterns.
## Default behavior
When no `get_locale` callback is provided, GT parses the `Accept-Language` header, matches against your configured `locales`, and falls back to `default_locale`:
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
initialize_gt(app, default_locale='en', locales=['es', 'fr'])
```
```python
from fastapi import FastAPI
from gt_fastapi import initialize_gt
app = FastAPI()
initialize_gt(app, default_locale='en', locales=['es', 'fr'])
```
## Chaining detection strategies
In production, you'll typically want to try multiple sources in priority order. Pass a `get_locale` callback to `initialize_gt`:
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
def get_locale(request) -> str:
# 1. Explicit query parameter
lang = request.args.get('lang')
if lang:
return lang
# 2. Cookie (user's saved preference)
locale = request.cookies.get('locale')
if locale:
return locale
# 3. URL path prefix (/es/about)
parts = request.path.strip('/').split('/')
if parts and parts[0] in ('es', 'fr', 'de'):
return parts[0]
# 4. Accept-Language header
accept = request.headers.get('Accept-Language', '')
if accept:
return accept.split(',')[0].split(';')[0].strip()
return 'en'
initialize_gt(app, default_locale='en', locales=['es', 'fr', 'de'], get_locale=get_locale)
```
```python
from fastapi import FastAPI, Request
from gt_fastapi import initialize_gt
app = FastAPI()
def get_locale(request: Request) -> str:
# 1. Explicit query parameter
lang = request.query_params.get('lang')
if lang:
return lang
# 2. Cookie (user's saved preference)
locale = request.cookies.get('locale')
if locale:
return locale
# 3. URL path prefix (/es/about)
parts = request.url.path.strip('/').split('/')
if parts and parts[0] in ('es', 'fr', 'de'):
return parts[0]
# 4. Accept-Language header
accept = request.headers.get('accept-language', '')
if accept:
return accept.split(',')[0].split(';')[0].strip()
return 'en'
initialize_gt(app, default_locale='en', locales=['es', 'fr', 'de'], get_locale=get_locale)
```
## Persisting locale with cookies
Let users choose their language and remember it:
```python
from flask import request, make_response, jsonify
@app.route('/api/set-language', methods=['POST'])
def set_language():
locale = request.json.get('locale', 'en')
response = make_response(jsonify({'ok': True}))
response.set_cookie('locale', locale, max_age=365 * 24 * 60 * 60)
return response
```
```python
from fastapi import Request
from fastapi.responses import JSONResponse
@app.post('/api/set-language')
async def set_language(request: Request):
body = await request.json()
locale = body.get('locale', 'en')
response = JSONResponse({'ok': True})
response.set_cookie('locale', locale, max_age=365 * 24 * 60 * 60)
return response
```
## User profile-based detection
For authenticated apps, pull the locale from user preferences:
```python
def get_locale(request) -> str:
user = get_current_user(request) # your auth logic
if user and user.preferred_locale:
return user.preferred_locale
# Fall back to cookie or header
return request.cookies.get('locale') or 'en'
```
## Reading the resolved locale
Use [`get_locale()`](/docs/python/api/get-locale) anywhere in your request handling to read back the resolved locale:
```python
from gt_flask import get_locale # or gt_fastapi
@app.route('/api/info')
def info():
return { 'locale': get_locale() }
```
## Next steps
- [Custom locale detection tutorial](/docs/python/tutorials/custom-locale-detection) — basic introduction
- [`get_locale()` API reference](/docs/python/api/get-locale)
- [String Translation Patterns](/docs/python/guides/strings) — how to translate content
# python: String Translation Patterns
URL: https://generaltranslation.com/en-US/docs/python/guides/strings.mdx
---
title: String Translation Patterns
description: Translating strings in Python with t(), msg(), variables, and derive()
---
There are two ways to translate strings in GT's Python libraries:
1. **Inline with `t()`** — translate strings directly in your route handlers
2. **Pre-registered with `msg()`** — define strings at module scope, resolve at runtime
## Inline translation with `t()`
Use [`t()`](/docs/python/api/t) to translate a string in the current request's locale:
```python
from gt_flask import t
@app.route('/api/greeting')
def greeting():
return { 'message': t('Hello, world!') }
```
```python
from gt_fastapi import t
@app.get('/api/greeting')
def greeting():
return { 'message': t('Hello, world!') }
```
## Pre-registered strings with `msg()`
Use [`msg()`](/docs/python/api/t) to register strings at module scope, then call them in handlers:
```python title="messages.py"
from gt_flask import msg # or gt_fastapi
GREETING = msg('Hello, world!')
WELCOME = msg('Welcome, {name}!')
NOT_FOUND = msg('Resource not found.')
```
```python title="routes.py"
from messages import GREETING, WELCOME, NOT_FOUND
@app.route('/api/greeting')
def greeting():
return {
'greeting': GREETING(),
'welcome': WELCOME(name='Alice'),
}
@app.errorhandler(404)
def not_found(e):
return { 'error': NOT_FOUND() }, 404
```
Both `t()` and `msg()` produce identical translations. Use `msg()` when the same string appears in multiple places or when you want all strings in one file.
## Variable interpolation
### With `t()`
Use `{name}` placeholders and pass values as keyword arguments:
```python
t('Welcome, {name}!', name=user.display_name)
t('You have {count} new messages.', count=unread_count)
```
### With `declare_var()` and `decode_vars()`
For more control over variable handling, use [`declare_var()`](/docs/python/api/declare-var) and [`decode_vars()`](/docs/python/api/decode-vars):
```python
from gt_flask import declare_var, decode_vars
template = t('Hello, {name}! You have {count} items.')
result = decode_vars(template, {
'name': declare_var('name', 'Guest'),
'count': declare_var('count', 0),
})
```
## Using `derive()` for word agreement
[`derive()`](/docs/python/api/derive) generates grammatically correct variants — useful for languages where words change form based on context (gender, number, case):
```python
from gt_flask import t, derive
count = 3
item_word = derive('item', {'one': 'item', 'other': 'items'})
message = t('You have {count} {item}.', count=count, item=item_word)
```
See the [derive tutorial](/docs/python/tutorials/derive) for more patterns.
## Using `$context` for disambiguation
Ambiguous strings can produce inaccurate translations. Add `$context` to guide the translator:
```python
t('Apple', context='the technology company')
t('Spring', context='the season, not a coil')
t('Bank', context='a financial institution')
# Also works with msg()
APPLE = msg('Apple', context='the fruit')
```
## Next steps
- [`t()` API reference](/docs/python/api/t)
- [`declare_var()` API reference](/docs/python/api/declare-var)
- [`derive()` API reference](/docs/python/api/derive)
- [Locale Detection & Middleware](/docs/python/guides/middleware) — how locale context works
# python: Custom locale detection
URL: https://generaltranslation.com/en-US/docs/python/tutorials/custom-locale-detection.mdx
---
title: Custom locale detection
description: How to customize locale detection with get_locale, and how the default behavior works
---
## Default behavior
When no `get_locale` callback is provided to [`initialize_gt`](/docs/python/api/initialize-gt), GT automatically detects the user's locale from the HTTP `Accept-Language` header on every request:
1. Reads the `Accept-Language` header (e.g. `en-US,en;q=0.9,es;q=0.8`)
2. Parses it into a list of locales sorted by quality value (highest first)
3. Matches against your configured `locales` to find the best fit
4. Falls back to `default_locale` if no match is found
This means out of the box, users get content in whatever language their browser requests — as long as you have translations for it.
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
# No get_locale — defaults to Accept-Language parsing
initialize_gt(
app,
default_locale="en",
locales=["es", "fr"],
)
```
```python
from fastapi import FastAPI
from gt_fastapi import initialize_gt
app = FastAPI()
# No get_locale — defaults to Accept-Language parsing
initialize_gt(
app,
default_locale="en",
locales=["es", "fr"],
)
```
---
## Custom `get_locale`
To override the default, pass a `get_locale` callback to `initialize_gt`. It receives the request object and must return a locale string.
```python
from flask import Flask
from gt_flask import initialize_gt
app = Flask(__name__)
def get_locale(request) -> str:
# Check query parameter first
locale = request.args.get("lang")
if locale:
return locale
# Then check a cookie
locale = request.cookies.get("locale")
if locale:
return locale
# Fall back to default
return "en"
initialize_gt(
app,
default_locale="en",
locales=["es", "fr"],
get_locale=get_locale,
)
```
```python
from fastapi import FastAPI, Request
from gt_fastapi import initialize_gt
app = FastAPI()
def get_locale(request: Request) -> str:
# Check query parameter first
locale = request.query_params.get("lang")
if locale:
return locale
# Then check a cookie
locale = request.cookies.get("locale")
if locale:
return locale
# Fall back to default
return "en"
initialize_gt(
app,
default_locale="en",
locales=["es", "fr"],
get_locale=get_locale,
)
```
---
## How it works internally
- **FastAPI**: `initialize_gt` registers an HTTP middleware that runs on every request. If `get_locale` is provided, it calls `get_locale(request)`. Otherwise it parses `Accept-Language`. The resolved locale is set on the `I18nManager`, which [`t()`](/docs/python/api/t) reads from.
- **Flask**: `initialize_gt` registers a `before_request` hook with the same logic.
---
## Common patterns
### URL path prefix
Extract the locale from the URL path (e.g. `/es/about`, `/fr/home`):
```python
def get_locale(request) -> str:
parts = request.url.path.strip("/").split("/")
supported = {"es", "fr", "de"}
if parts and parts[0] in supported:
return parts[0]
return "en"
```
### User profile
Look up the locale from an authenticated user's preferences:
```python
def get_locale(request) -> str:
user = get_current_user(request) # your auth logic
if user and user.preferred_locale:
return user.preferred_locale
return "en"
```
### Subdomain
Detect locale from a subdomain like `es.example.com`:
```python
def get_locale(request) -> str:
host = request.headers.get("host", "")
subdomain = host.split(".")[0]
if subdomain in ("es", "fr", "de"):
return subdomain
return "en"
```
---
## Notes
- Your `get_locale` function should always return a valid locale string
- If it returns a locale you don't have translations for, `t()` will fall back to the original content in `default_locale`
- The function receives the raw framework request object — `Request` for FastAPI, Flask's `request` for Flask
- You can use [`get_locale()`](/docs/python/api/get-locale) elsewhere in your code to read back the resolved locale
# python: Using derive
URL: https://generaltranslation.com/en-US/docs/python/tutorials/derive.mdx
---
title: Using derive
description: How to use derive for word agreement, reusable content, and static analysis
---
## What is `derive`?
[`derive`](/docs/python/api/derive) is an identity function that marks content for the GT CLI's static analysis. When the CLI scans your code, it recognizes `derive(...)` calls and determines all possible return values, creating a separate translation entry for each.
This is useful for:
- Preserving **word agreement** across languages (gender, plurality, case)
- **Reusable content** with function calls inside translated strings
- **Fragmented sentences** where part of the string has a known set of outcomes
---
## Preserving word agreement
Languages have grammatical rules (gender, plurality, case) that affect surrounding words. Without `derive`, a single translation entry can't handle agreement:
```python
# Without derive — one translation, no agreement possible
message = t(f"The {get_subject(gender)} is playing.")
# "The boy is playing." and "The girl is playing." share one translation
```
With `derive`, the CLI creates separate entries for each outcome:
```python
from gt_flask import derive, t
def get_subject(gender: str) -> str:
return "boy" if gender == "male" else "girl"
message = t(f"The {derive(get_subject(gender))} is playing.")
```
This produces two translation entries:
- `"The boy is playing."` → `"El niño está jugando."`
- `"The girl is playing."` → `"La niña está jugando."`
Notice how Spanish uses "El" vs "La" depending on the subject — agreement is handled automatically.
---
## How it works
1. **At build time**, the GT CLI analyzes expressions wrapped by `derive`
2. It determines all possible return values (these must be statically analyzable)
3. It creates separate translation entries for each unique outcome
4. **At runtime**, `derive` is just an identity function — it returns its argument unchanged
---
## Examples
### Inline expressions
You can embed logic directly inside `derive`:
```python
from gt_flask import derive, t
message = t(f"The {derive('boy' if gender == 'male' else 'girl')} is playing.")
```
### Function calls
Wrap function calls that have a known set of return values:
```python
from gt_flask import derive, t
def get_status_label(status: str) -> str:
if status == "complete":
return "completed"
elif status == "pending":
return "pending"
return "unknown"
message = t(f"Task is {derive(get_status_label(status))}.")
```
### Reusable content
```python
from gt_flask import derive, t
def get_subject() -> str:
return "boy"
translation1 = t(f"The {derive(get_subject())} is playing.")
translation2 = t(f"The {derive(get_subject())} is having fun.")
```
### With `declare_var`
Combine `derive` with [`declare_var`](/docs/python/api/declare-var) when you need dynamic content inside a static expression:
```python
from gt_flask import derive, declare_var, t
def get_greeting(name: str | None) -> str:
if name:
return f"Hello, {declare_var(name, name='user')}"
return "Hello, stranger"
message = t(f"{derive(get_greeting(name))}! How are you?")
```
---
## Performance considerations
`derive` multiplies translation entries. Each call with N possible outcomes creates N entries, and multiple `derive` calls in the same string multiply exponentially. Use judiciously.
# python: FastAPI Quickstart
URL: https://generaltranslation.com/en-US/docs/python/tutorials/fastapi-quickstart.mdx
---
title: FastAPI Quickstart
description: Add internationalization to your FastAPI app with gt-fastapi
---
**Experimental:** `gt-fastapi` is experimental and may be subject to breaking changes.
## Install
```bash
pip install gt-fastapi
```
## Create a config file
Create a `gt.config.json` in your project root:
```json title="gt.config.json"
{
"projectId": "your-project-id",
"defaultLocale": "en",
"locales": ["es", "fr"]
}
```
## Initialize
`initialize_gt` automatically reads `gt.config.json` from the current working directory. If your config file is located elsewhere, pass the path with `config_path`:
```python title="app.py"
from fastapi import FastAPI
from gt_fastapi import initialize_gt, t
app = FastAPI()
initialize_gt(app)
# or: initialize_gt(app, config_path="path/to/gt.config.json")
```
## Translate strings
Use the `t` function in your routes:
```python title="app.py"
@app.get("/")
def index():
return {"message": t("Hello, world!")}
```
## Next steps
- See [`t`](/docs/python/api/t) for variable interpolation and options.
- See [`initialize_gt`](/docs/python/api/initialize-gt) for all configuration options.
# python: Flask Quickstart
URL: https://generaltranslation.com/en-US/docs/python/tutorials/flask-quickstart.mdx
---
title: Flask Quickstart
description: Add internationalization to your Flask app with gt-flask
---
**Experimental:** `gt-flask` is experimental and may be subject to breaking changes.
## Install
```bash
pip install gt-flask
```
## Create a config file
Create a `gt.config.json` in your project root:
```json title="gt.config.json"
{
"projectId": "your-project-id",
"defaultLocale": "en",
"locales": ["es", "fr"]
}
```
## Initialize
`initialize_gt` automatically reads `gt.config.json` from the current working directory. If your config file is located elsewhere, pass the path with `config_path`:
```python title="app.py"
from flask import Flask
from gt_flask import initialize_gt, t
app = Flask(__name__)
initialize_gt(app)
# or: initialize_gt(app, config_path="path/to/gt.config.json")
```
## Translate strings
Use the `t` function in your routes:
```python title="app.py"
@app.get("/")
def index():
return {"message": t("Hello, world!")}
```
## Next steps
- See [`t`](/docs/python/api/t) for variable interpolation and options.
- See [`initialize_gt`](/docs/python/api/initialize-gt) for all configuration options.
# gt-react: General Translation React SDK: Compiler
URL: https://generaltranslation.com/en-US/docs/react/concepts/compiler.mdx
---
title: Compiler
description: How the gt CLI processes your React source files
---
The `gt` CLI includes a compiler that analyzes your React source files at build time. It catches common translation errors and can optionally automate wrapping JSX in translation components.
## Features
### Dynamic content detection
Detects unwrapped dynamic content in translation components:
```jsx
// ❌ Invalid - dynamic content not wrapped
Hello {userName}
// ✅ Valid - dynamic content wrapped in variable component
Hello {userName}
```
### Function call validation
Detects non-literal arguments passed to translation functions:
```jsx
const gt = useGT();
// ❌ Invalid - template literals and concatenation
gt(`Hello ${name}`)
gt("Hello " + name)
// ✅ Valid - string literals with variable substitution
gt("Hello, {name}!", { name })
```
## Auto JSX injection
With auto JSX injection enabled, the compiler automatically wraps translatable JSX text in translation components — so you don't need to manually add `` components around every piece of text.
### Enabling auto JSX injection
Add `enableAutoJsxInjection` to your `gt.config.json`:
```json title="gt.config.json"
{
"files": {
"gt": {
"output": "public/_gt/[locale].json",
"parsingFlags": {
"enableAutoJsxInjection": true
}
}
}
}
```
### Before and after
Without auto JSX injection, you wrap text manually:
```jsx
import { T } from 'gt-react';
function Welcome() {
return (
Welcome to our app
);
}
```
With auto JSX injection enabled, you write plain JSX and the compiler handles the rest:
```jsx
function Welcome() {
return Welcome to our app ;
}
```
The compiler detects the translatable text and wraps it automatically when you run `npx gt translate`.
### What the compiler respects
- **User-written `` components** are left untouched — the compiler won't double-wrap your code
- **Other GT components** like ``, ``, ``, and `` are also respected
- **String attributes** (e.g., `placeholder`, `alt`) are not affected — only JSX children are wrapped
- **Non-text content** like numbers and booleans is ignored
# gt-react: General Translation React SDK: Production vs Development
URL: https://generaltranslation.com/en-US/docs/react/concepts/environments.mdx
---
title: Production vs Development
description: Differences between production and development environments
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Overview
`gt-react` behaves differently depending on the environment your React application is running in.
It detects the environment by checking the `NODE_ENV` environment variable.
## Production behavior
### Environment variables
In production, the only accepted environment variable is `GT_PROJECT_ID` (or a prefixed version thereof, such as `NEXT_PUBLIC_GT_PROJECT_ID`).
If an API key is provided as an environment variable, `gt-react` will throw an error. This is to prevent API keys from being exposed to the client.
### Translation loading behavior
In production, the `gt-react` provider will attempt to load translations from the General Translation CDN, by default.
If you have configured custom translation loading behavior, such as local translations, via the `loadTranslations` function `gt-react` will use that instead.
Translation hot reloading is disabled since it is in production.
## Development behavior
### Environment variables
Since development is local and not exposed to foreign users, `gt-react` will accept any General Translation environment variables, even if they are prefixed with `NEXT_PUBLIC_`, `VITE_`, (or similar).
### Translation loading behavior
In development, the `gt-react` provider will first attempt to load translations in the same way as production.
These translations are loaded into memory.
When rendering a component (that uses `useGT`, ``, or `useTranslations`) in a language different than the default, the `gt-react` provider will do the following:
1. If it detects a valid, stored translation for the given content, it will render the translation.
2. If no translation is found, it will attempt to dynamically translate the content via the General Translation API.
3. After translating, the translation will be rendered, and stored in memory for future use.
4. If the translation times out, it will fallback and render the original content.
Our API also internally caches development translations for a short period of time, so if the same translation is requested again, it will be served from cache.
These translations are isolated at the project level, so they will not be mixed up with translations from other projects.
Additionally, the cache is unique to development sessions, so cached translations will not be used in production.
`gt-react` will detect changes to components that use `useGT`, ``, or `useTranslations` and will dynamically translate the modified content via our API.
## Production vs development API keys [#api-keys]
To help distinguish between the production and development behavior of `gt-react`, we have the concept of "Production API Keys" and "Development API Keys".
### Production API keys
Production API keys are API keys beginning with `gtx-api-`.
When a Production API key is provided, `gt-react` will behave as described in the [Production Behavior](#production-behavior) section.
This means that if you are running your React application in development mode, and you provide a Production API key, `gt-react` will behave as if you are in production.
Translation hot reloading will be disabled, and components without translations will render the original content.
Other than this behavior, `gt-react` will not utilize the Production API key in any way.
The reason why we ask you to create a separate, production API key when shipping to production is because the CLI tool only accesses Production API keys.
The CLI tool will apply billing and rate-limiting using the "production" category.
### Development API keys
Development API keys are API keys beginning with `gtx-dev-`.
When a Development API key is provided, `gt-react` will behave as described in the [Development Behavior](#development-behavior) section.
When using a Development API key, billing and rate-limiting will be applied using the "development" category.
Translations created with a Development API key will not be stored, and will not be available for use in production.
The purpose of development translations is to allow you to test your application before shipping to production.
# gt-react: General Translation React SDK: Standalone i18n
URL: https://generaltranslation.com/en-US/docs/react/concepts/stand-alone.mdx
---
title: Standalone i18n
description: How to use gt-react as a standalone i18n library
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Overview
`gt-react` has feature parity with many other i18n libraries.
This means that you can use `gt-react` as a standalone i18n library, without using the General Translation platform.
To do this, don't provide any environment variables such as `GT_API_KEY` or `GT_PROJECT_ID`.
See our [migration guide](/docs/react/guides/migration) for more information on how to migrate from another i18n library to `gt-react`.
## Tradeoffs
Using `gt-react` as a standalone i18n library has some tradeoffs.
### Manual translation
You will need to manually translate your app. If you use our platform, we automatically translate your app for you.
If your project only uses [dictionaries](/docs/react/guides/dictionaries) with the `useTranslations` function,
you'll need to manually translate your dictionaries, as you would with any other i18n library.
Make sure you load your translated dictionaries with the [`loadDictionary`](/docs/react/api/config/load-dictionary) function.
---
### Manual string translation
If your project is using inline translations with the [``](/docs/react/guides/t) component
or the [`useGT`](/docs/react/guides/strings) functions,
you'll also need to manually translate your strings.
Since there are no keys with inline translations, the CLI tool has a command: [`gt generate`](/docs/cli/generate)
which will automatically generate template files for your project. You'll just need to edit the template files with your translations for each language.
Make sure you load your translated strings with the [`loadTranslations`](/docs/react/api/config/load-translations) function.
### No development translations
# gt-react: General Translation React SDK: Branching Components
URL: https://generaltranslation.com/en-US/docs/react/guides/branches.mdx
---
title: Branching Components
description: How to use branching components for conditional content within translations
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Branching components enable conditional content rendering within [``](/docs/react/api/components/t) components. They handle dynamic logic like if/else statements and pluralization rules while ensuring all content variations can be properly translated.
## Available components
- [``](/docs/react/api/components/branch): Conditional content based on values or states
- [``](/docs/react/api/components/plural): Automatic pluralization using locale-specific rules
## Quickstart
Branching components work inside [``](/docs/react/api/components/t) to handle conditional logic:
```jsx
import { T, Branch, Plural, Num, Var } from 'gt-react';
function NotificationPanel({ user, messageCount }) {
return (
{user.name} is currently online}
away={{user.name} is away
}
>
{user.name} status unknown
You have {messageCount} message}
other={You have {messageCount} messages
}
/>
);
}
```
## How branching components work
Branching components solve conditional rendering within translations by:
1. **Replacing ternary operators** and conditional logic inside [``](/docs/react/api/components/t)
2. **Providing fallback content** when conditions don't match expected values
3. **Enabling translation** of all possible content variations
4. **Following locale rules** for pluralization automatically
```jsx
// ❌ This breaks - conditional logic in
{isActive ? 'User is active' : 'User is inactive'}
// ✅ This works - conditional logic with branching
User is active}
false={User is inactive
}
/>
```
## Component guide
### Branch - Conditional content
Use [``](/docs/react/api/components/branch) for any conditional rendering based on values or states:
```jsx
// User status display
Administrator Dashboard}
user={User Dashboard
}
guest={Guest Access
}
>
Access level unknown
// Boolean conditions
Welcome back!}
false={Please log in
}
/>
// Subscription tiers
Upgrade to unlock premium features}
premium={Enjoy your premium experience
}
enterprise={Contact support for enterprise solutions
}
>
Subscription status unavailable
```
### Plural - Smart pluralization
Use [``](/docs/react/api/components/plural) for content that changes based on quantity:
```jsx
// Basic pluralization
{itemCount} item in cart}
other={{itemCount} items in cart
}
/>
// Zero handling
No new notifications}
one={{notifications} notification
}
other={{notifications} notifications
}
/>
// Complex pluralization (follows Unicode CLDR rules)
Due today}
one={Due in {days} day
}
few={Due in {days} days
}
many={Due in {days} days
}
other={Due in {days} days
}
/>
```
### Combining with variable components
Branching and variable components work together seamlessly:
```jsx
Order {order.id} is pending.
Total: {order.total}
}
shipped={
Order {order.id} shipped on {order.shippedDate}
}
delivered={
Order {order.id} was delivered successfully
}
>
Order status unknown
```
## When to use branching components
### Replace ternary operators
Convert conditional logic for use within [``](/docs/react/api/components/t):
```jsx
// ❌ Can't use ternary in
{isActive ? Active user
: Inactive user
}
// ✅ Use Branch instead
Active user}
false={Inactive user
}
/>
```
### Handle multiple conditions
Replace switch statements or multiple if/else conditions:
```jsx
// ❌ Complex conditional logic
{status === 'loading' ? Loading...
:
status === 'error' ? Error occurred
:
status === 'success' ? Success!
:
Unknown status
}
// ✅ Clean branching logic
Loading...}
error={Error occurred
}
success={Success!
}
>
Unknown status
```
### Pluralization rules
Replace manual plural handling:
```jsx
// ❌ Manual pluralization
{count === 1 ? 1 item
: {count} items
}
// ✅ Automatic pluralization
{count} item}
other={{count} items
}
/>
```
## Standalone usage
Branching components can be used outside [``](/docs/react/api/components/t) for pure logic without translation:
```jsx
// Pure conditional rendering
}
light={ }
>
// Pure pluralization
}
other={ }
/>
```
## Common issues
### Missing branch keys
Always provide fallback content for unmatched values:
```jsx
// ❌ No fallback for unexpected values
}
user={ }
// What if userRole is "moderator"?
/>
// ✅ Always include fallback
}
user={ }
>
{/* Fallback for any other value */}
```
### Incomplete plural forms
Provide necessary plural forms for your default locale:
```jsx
// ❌ Missing "other" form
1 item}
// What about 0, 2, 3, etc.?
/>
// ✅ Include required forms
No items}
one={1 item
}
other={{count} items
}
/>
```
### Complex nested logic
Although this works, we recommend keeping branching logic simple and avoid deep nesting:
```jsx
// ❌ Complex nested branching
{/* Hard to read and maintain */}
// ✅ Flatten logic or use multiple components
}
active-offline={ }
inactive-online={ }
>
```
Learn more about pluralization rules in the [Unicode CLDR documentation](https://cldr.unicode.org/index/cldr-spec/plural-rules).
## Next steps
- [String Translation Guide](/docs/react/guides/strings) - Translate plain text without JSX
- [Dynamic Content Guide](/docs/key-concepts/dynamic-content) - Handle runtime translation
- API References:
- [`` Component](/docs/react/api/components/branch)
# gt-react: General Translation React SDK: Dictionaries
URL: https://generaltranslation.com/en-US/docs/react/guides/dictionaries.mdx
---
title: Dictionaries
description: How to use traditional dictionary-based translation patterns
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Dictionaries provide a traditional approach to organizing translations in nested objects with key-value pairs. While [`` components](/docs/react/guides/t) are the recommended approach, dictionaries can be useful for migration from other i18n libraries or when you prefer centralized translation storage.
**Recommendation:** Use [`` components](/docs/react/guides/t) for new projects. Dictionaries are supported primarily for migration and compatibility with existing translation workflows.
## Dictionary vs component translation
### Dictionary pattern
```tsx
// dictionary.ts
export default {
greetings: {
hello: 'Hello, world!',
welcome: 'Welcome, {name}!'
}
};
// Component usage
function MyComponent() {
const t = useTranslations();
return {t('greetings.hello')}
;
}
```
### Component pattern
```tsx
// Direct component usage - recommended
function MyComponent() {
return Hello, world!
;
}
```
## Trade-offs
### Dictionary advantages
- **Centralized storage** - All translations in one place
- **Industry standard** - Familiar pattern from other i18n libraries
- **Migration friendly** - Easy to port existing translations
### Dictionary disadvantages
- **Complexity** - More setup and configuration required
- **Maintainability** - Content separated from usage makes updates harder
- **Debuggability** - Harder to trace translations back to components
- **Readability** - Keys don't show actual content
## Quickstart
### Step 1: Create dictionary
Create a dictionary file in your project root or `src` directory:
```ts title="dictionary.ts"
const dictionary = {
greetings: {
hello: 'Hello, world!',
welcome: 'Welcome to our app!'
},
navigation: {
home: 'Home',
about: 'About',
contact: 'Contact'
}
};
export default dictionary;
```
Or use JSON format:
```json title="dictionary.json"
{
"greetings": {
"hello": "Hello, world!",
"welcome": "Welcome to our app!"
},
"navigation": {
"home": "Home",
"about": "About",
"contact": "Contact"
}
}
```
Then you pass it to your [``](/docs/react/api/components/gtprovider) component:
```jsx title="index.js" copy
import dictionary from "./dictionary.js";
import config from "./gt.config.json";
createRoot(document.getElementById("root")!).render(
{/* [!code highlight] */}
);
```
### Step 2: Use in components
The [`useTranslations`](/docs/react/api/dictionary/use-translations) hook lets you access dictionary entries:
```tsx
import { useTranslations } from 'gt-react';
function MyComponent() {
const t = useTranslations();
return (
{t('greetings.hello')}
{t('greetings.welcome')}
);
}
```
## Using variables
Add variables to dictionary entries using `{variable}` syntax:
```ts title="dictionary.ts"
const dictionary = {
user: {
greeting: 'Hello, {name}!',
itemCount: 'You have {count} items',
orderTotal: 'Total: ${amount}'
}
};
```
```tsx
function UserDashboard() {
const t = useTranslations();
return (
{t('user.greeting', { name: 'Alice' })}
{t('user.itemCount', { count: 5 })}
{t('user.orderTotal', { amount: 99.99 })}
);
}
```
## Using prefixes
Scope dictionary access to specific sections using prefixes:
```ts title="dictionary.ts"
const dictionary = {
dashboard: {
header: {
welcome: 'Welcome back!',
lastLogin: 'Last login: {date}'
},
stats: {
totalUsers: 'Total Users: {count}',
activeUsers: 'Active Users: {count}'
}
}
};
```
```tsx
function DashboardHeader() {
// Prefix limits access to 'dashboard.header'
const t = useTranslations('dashboard.header');
return (
);
}
function DashboardStats() {
// Different prefix for stats section
const t = useTranslations('dashboard.stats');
return (
{t('totalUsers', { count: 1000 })}
{/* -> dashboard.stats.totalUsers */}
{t('activeUsers', { count: 150 })}
{/* -> dashboard.stats.activeUsers */}
);
}
```
## Multiple language support
### Automatic translation (recommended)
Most users should use [`loadTranslations`](/docs/react/api/config/load-translations) to automatically generate translations from your base dictionary:
```ts title="dictionary.ts"
const dictionary = {
common: {
save: 'Save',
cancel: 'Cancel',
delete: 'Delete'
},
forms: {
required: 'This field is required',
email: 'Please enter a valid email'
}
};
export default dictionary;
```
Then create a `loadTranslations` function to load generated translation files:
```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
const translations = await import(`./_gt/${locale}.json`);
return translations.default;
}
```
Pass it to your ``:
```tsx title="src/index.tsx"
import loadTranslations from './loadTranslations';
import dictionary from './dictionary';
createRoot(document.getElementById("root")!).render(
);
```
GT automatically generates translations for other languages based on your base dictionary. Run `npx gt translate` to generate translations for all configured languages.
### Manual translation files (migration)
For migration from other i18n libraries or manual translation management, use [`loadDictionary`](/docs/react/api/config/load-dictionary):
```ts title="src/loadDictionary.ts"
export default async function loadDictionary(locale: string) {
const translations = await import(`../public/locales/${locale}.json`);
return translations.default;
}
```
This loads JSON translation files from your `public/locales/` directory:
**Choose the right approach:** Use [`loadTranslations`](/docs/react/api/config/load-translations) for new projects with automatic translation generation, or [`loadDictionary`](/docs/react/api/config/load-dictionary) when migrating existing translation files.
## Production setup
### Build process
Add translation to your build pipeline:
```json title="package.json"
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
### Development vs production behavior
- **Development**: Dictionary entries translated on-demand with dev API key
- **Production**: All dictionary translations pre-built during build step
## Combining with components
Dictionaries and [`` components](/docs/react/guides/t) can work together:
```tsx
function MixedApproach() {
const t = useTranslations();
return (
{/* Dictionary for simple strings */}
{t('page.title')}
{/* T component for complex JSX */}
This is a complex message with links .
{/* Dictionary for form labels */}
{t('forms.email')}
);
}
```
## Next steps
**See it in action:** Check out the [dictionary pattern example app](https://github.com/gt-examples/dictionary-pattern) for a working demo — [live preview](https://dictionary-pattern.generaltranslation.dev).
- [Languages Guide](/docs/react/guides/languages) - Configure supported languages and locale settings
- [Dynamic Content Guide](/docs/key-concepts/dynamic-content) - Handle runtime translation needs
- API References:
- [`useTranslations` Hook](/docs/react/api/dictionary/use-translations)
# gt-react: General Translation React SDK: Changing Languages
URL: https://generaltranslation.com/en-US/docs/react/guides/languages.mdx
---
title: Changing Languages
description: How to configure and switch between languages in your React app
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Language switching allows users to change their preferred locale for your application's content. GT React provides several approaches from simple programmatic switching to pre-built UI components for custom language selectors.
## Available methods
- **Programmatic**: [`useSetLocale`](/docs/react/api/helpers/use-set-locale) hook for custom controls
- **Pre-built UI**: [``](/docs/react/api/components/locale-selector) component with dropdown
- **Custom UI**: [`useLocaleSelector`](/docs/react/api/helpers/use-locale-selector) hook for building custom selectors
## Using the `useSetLocale` hook
The [`useSetLocale`](/docs/react/api/helpers/use-set-locale) hook allows you to change the language of your app:
```tsx
import { useSetLocale } from 'gt-react';
export default function MyComponent() {
const setLocale = useSetLocale();
return setLocale('en')}>Set Locale ;
}
```
Simply provide the locale you want to change to as the argument to the function returned by the hook.
## Using the `` component
The [``](/docs/react/api/components/locale-selector) component provides a ready-to-use dropdown that automatically shows all configured locales:
```tsx
import { LocaleSelector } from 'gt-react';
export default function MyComponent() {
return ;
}
```
This component automatically:
- Shows all configured locales for your project
- Displays locales in their native language names
- Handles the switching logic
- Maintains current selection state
## Using the `useLocaleSelector` hook
If you want to build your own custom locale selector component, use [`useLocaleSelector`](/docs/react/api/helpers/use-locale-selector):
```tsx
import { useLocaleSelector } from 'gt-react';
function CustomLocaleSelector() {
const {
locale, // Current active locale (e.g., 'en', 'es')
locales, // Array of locales your project supports ['en', 'es', 'fr']
setLocale, // Function to change the locale: setLocale('es')
getLocaleProperties // Function to get display info for a locale
} = useLocaleSelector();
if (!locales?.length) return null;
return (
setLocale(e.target.value)}
>
{locales.map((loc) => {
const props = getLocaleProperties(loc);
return (
{props.nativeNameWithRegionCode} {/* e.g., "English (US)", "Español (ES)" */}
);
})}
);
}
```
## Important notes
### GTProvider requirement
Language switching components must be used within a [``](/docs/react/api/components/gtprovider):
```tsx
// ✅ Correct
// ❌ Wrong - outside provider
```
## Next steps
- [Dynamic Content Guide](/docs/key-concepts/dynamic-content) - Runtime content translation
- API References:
- [`useSetLocale` Hook](/docs/react/api/helpers/use-set-locale)
- [`` Component](/docs/react/api/components/locale-selector)
- [`useLocaleSelector` Hook](/docs/react/api/helpers/use-locale-selector)
# gt-react: General Translation React SDK: Local Translation Storage
URL: https://generaltranslation.com/en-US/docs/react/guides/local-tx.mdx
---
title: Local Translation Storage
description: Store translations in your app bundle instead of using a CDN
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## What are local translations?
Local translations are stored in your app's bundle, as opposed to being fetched from a CDN (Content Distribution Network). When you add the `gt translate` command to your build process, this generates translations in JSON format. The final step is getting these translations into your app where they can be used.
There are two ways to do this:
1. **In your app's bundle** (local): Save translations to your app's bundle after generation
2. **In a CDN** (default): Fetch translations from a CDN at runtime
By default, `gt-react` fetches translations from the General Translation CDN. When translating your app using our API, translations are automatically saved to our CDN.
**Default behavior:** GT uses CDN storage by default. Only switch to local storage if you need the specific benefits it provides.
## Trade-offs
### Benefits of local translations
- **Faster load times**: Local translations are served directly from your app, loading faster than translations served from a CDN
- **No reliance on external services**: Your app's ability to load translations isn't dependent on CDN uptime. If translations aren't found for a locale, the app automatically falls back to the default language
- **Works offline**: Translations are bundled with your app
### Drawbacks of local translations
- **Increased bundle size**: Local translations increase your app's bundle size, potentially making the app slower to load initially
- **Content management**: To edit a translation, you must redeploy your app with the new translation every time you make changes
## Setup
### Step 1: Create load function
Add a `loadTranslations.[js|ts]` file under `./src` with the following content:
```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
const t = await import(`./_gt/${locale}.json`);
return t.default;
}
```
### Step 2: Configure GTProvider
Pass `loadTranslations` as a prop to the [``](/docs/react/api/components/gtprovider) component:
```tsx title="src/App.tsx"
import { GTProvider } from 'gt-react';
import loadTranslations from './loadTranslations';
export default function App() {
return (
);
}
```
### Step 3: Configure CLI
Run the configuration command and select local storage:
```bash
npx gt configure
```
When prompted:
- **Save to CDN?** Select "No"
- **Translation directory:** The CLI will automatically use `./src/_gt`
Alternatively, you can manually configure the `gt.config.json` file to use local translations. See the [CLI Configuration docs](/docs/cli/reference/config) for more information.
### Step 4: Generate translations
Now when you run the translate command, translations will be automatically downloaded and included in your codebase:
```bash
npx gt translate
```
Translations will be stored in `src/_gt/` and bundled with your app.
## Build integration
### React build process
Add translation generation to your build script:
```json
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
### CI/CD pipeline
```yaml
# .github/workflows/deploy.yml
- name: Generate Translations
run: npx gt translate
- name: Build Application
run: npm run build
```
## Common issues
### Missing translation files
Ensure translations are generated before building:
```bash
# ❌ Build without translations
<...YOUR_BUILD_COMMAND...>
# ✅ Generate translations first
npx gt translate && <...YOUR_BUILD_COMMAND...>
```
### Import path errors
Match your directory structure in the load function:
```ts
// ❌ Wrong path
const t = await import(`../translations/${locale}.json`);
// ✅ Correct path for src/_gt
const t = await import(`./_gt/${locale}.json`);
```
### Large bundle size
Consider code splitting for apps with many languages:
```ts
// Load translations only when needed
export default async function loadTranslations(locale: string) {
// Only load if locale is active
if (locale === getCurrentLocale()) {
const translations = await import(`./_gt/${locale}.json`);
return translations.default;
}
return {};
}
```
Local storage works best for apps with stable translations that don't need frequent updates.
## Next steps
- [Languages Guide](/docs/react/guides/languages) - Configure supported languages
# gt-react: General Translation React SDK: Migrating
URL: https://generaltranslation.com/en-US/docs/react/guides/migration.mdx
---
title: Migrating
description: Learn how to migrate a project to gt-react
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Overview
This guide will cover the steps needed to migrate a project that's already using an i18n library to `gt-react`.
We'll also provide some tips and suggestions for how to make the migration as smooth as possible.
## Prerequisites
- A project that is currently using another i18n library.
- A basic understanding of the `gt-react` library.
## Why migrate?
There are many reasons why you might want to migrate your project to `gt-react`.
Here are just a few:
- **No more JSON files:** Never manage translations in JSON files again.
All of your content lives inline with your code, where it belongs.
- **Automatic translations:** Generate high quality, context-aware translations with our CLI tool.
You'll never have to wait for translations again.
- **Experiment in dev:** Easily experiment with translations in development with translation hot-reloading.
## Setup
Install `gt-react` and the `gt` CLI tool.
```bash
npm i gt-react
npm i gt
```
```bash
yarn add gt-react
yarn add --dev gt
```
```bash
bun add gt-react
bun add --dev gt
```
```bash
pnpm add gt-react
pnpm add --save-dev gt
```
Create a `gt.config.json` file in the root of your project containing a `defaultLocale` property and a `locales` array.
```json title="gt.config.json" copy
{
"defaultLocale": "en",
"locales": ["en", "fr", "es"]
}
```
Add the `` component to the root of your app, and spread the `config` object as props.
```tsx
import { GTProvider } from 'gt-react'
import config from './gt.config.json'
```
For more detailed steps, see the [project quickstart](/docs/react) guide.
At this point, you have 3 options:
1. Fully migrate your entire project to `gt-react`, and remove the old i18n library.
2. Fully migrate your project, but keep using dictionaries from the old i18n library.
2. Keep using the old i18n library for now, and only migrate part of your project to `gt-react`.
For more details on each option, see the [migration strategies](#strategies) section.
## Migration strategies [#strategies]
### Option 1: Fully migrate your entire project
This option is the most straightforward, and will also require the most code changes in one go.
After you've set up your project, you'll need to search for all instances of your old i18n library and replace them with `gt-react`.
If your app is using React hooks such as `useTranslation`, search for all instances of `useTranslation` in your codebase and replace them with `useGT`.
Then, you'll need to replace all the string keys with their actual string values.
For example, if your old code looks like this:
```json title="dictionary.json"
{
"hello": {
"description": "Hello, world!"
}
}
```
```tsx
export default function MyComponent() {
const { t } = useTranslation()
return {t('hello.description')}
}
```
You'll need to replace it with:
```tsx
export default function MyComponent() {
const { t } = useGT()
return {t('Hello, world!')}
}
// OR
export default function MyComponent() {
return Hello, world!
}
```
Do this for all instances of your old i18n library.
### Option 2: Fully migrate your project, but keep using dictionaries from the old i18n library
Let's say that you want to migrate your project to `gt-react`, but you want to keep using dictionaries from the old i18n library
and only use GT inline features for new content.
In this case, you can do something similar to Option 1:
Find all instances of your old i18n library, such as `useTranslation` hooks, and replace them with `useTranslations` hooks.
The `useTranslations` hook behaves very similarly to `useTranslation` hooks, and you can use it in the same way.
```tsx
import { useTranslation } from 'react-i18next'
export default function MyComponent() {
const { t } = useTranslation()
return {t('hello.description')}
}
```
```tsx
import { useTranslations } from 'gt-react'
export default function MyComponent() {
const t = useTranslations()
return {t('hello.description')}
}
```
In terms of configuration, you'll need to create a `dictionary.[js|ts|json]` file in your project root or `src` directory.
Copy the contents of your old dictionary file into this new file, then pass it to the `GTProvider` component.
```tsx
import { GTProvider } from 'gt-react'
import dictionary from './dictionary.json'
import config from './gt.config.json'
```
See the [dictionaries](/docs/react/guides/dictionaries) guide for more details.
### Option 3: Keep using the old i18n library for now, and only migrate part of your project to `gt-react`
This option is the most flexible, and will require the least code changes in one go.
In this case, you can do something similar to Option 2, but only migrate part of your project to `gt-react`.
For example, you can keep using the old i18n library for some components, and only use `gt-react` for others and for new content.
This option is not recommended, as you will have to manage two different i18n libraries in your project, which may be complex and lead to bugs.
## Migration tips
### 1. Use the `useGT` hook or `` component as much as possible
Wherever possible, we recommend using the `useGT` hook or `` component.
This will make editing your content much easier in the future, and make your codebase much more readable.
### 2. Use the `useTranslations` hook for existing content
The `useTranslations` hook is a great way to keep using your existing dictionaries.
We offer it as a way to make migration easier, but we don't recommend using it for new content.
### 3. Using AI
If you are using AI to help you migrate your project, we have a `LLMs.txt` and `LLMs-full.txt` available at:
- [LLMs.txt](/llms.txt)
- [LLMs-full.txt](/llms-full.txt)
These files contain the full content of these docs, so your AI tool will have access to all the information it needs to help you migrate your project.
# gt-react: General Translation React SDK: Shared Strings
URL: https://generaltranslation.com/en-US/docs/react/guides/shared-strings.mdx
---
title: Shared Strings
description: How to internationalize strings used across multiple components and files
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Shared strings are text values used in multiple places throughout your application - like navigation labels, form messages, or configuration data. Instead of duplicating translation logic everywhere, use [`msg`](/docs/react/api/strings/msg) to mark strings for translation and [`useMessages`](/docs/react/api/strings/use-messages) to decode them.
## The problem with shared content
Consider this navigation configuration used across your app:
```tsx
// navData.ts
export const navData = [
{
label: 'Home',
description: 'The home page',
href: '/'
},
{
label: 'About',
description: 'Information about the company',
href: '/about'
}
];
```
To internationalize this, you'd typically need to:
1. Convert it to a function that accepts a translation function
2. Update every usage to call the function with `t`
3. Manage the complexity across your codebase
This creates maintenance overhead and makes your code harder to read. The [`msg`](/docs/react/api/strings/msg) function solves this by letting you mark strings for translation in-place, then decode them when needed.
## Quickstart
Use [`msg`](/docs/react/api/strings/msg) to mark strings and [`useMessages`](/docs/react/api/strings/use-messages) to decode them:
```tsx
// navData.ts - Mark strings for translation
import { msg } from 'gt-react';
export const navData = [
{
label: msg('Home'),
description: msg('The home page'),
href: '/'
},
{
label: msg('About'),
description: msg('Information about the company'),
href: '/about'
}
];
```
```tsx
// Component usage - Decode marked strings
import { useMessages } from 'gt-react';
import { navData } from './navData';
function Navigation() {
const m = useMessages();
return (
{navData.map((item) => (
{m(item.label)}
))}
);
}
```
## How shared strings work
The shared string system works in two phases:
1. **Mark Phase**: [`msg`](/docs/react/api/strings/msg) encodes strings with translation metadata
2. **Decode Phase**: [`useMessages`](/docs/react/api/strings/use-messages) decodes and translates the strings
```tsx
// msg() encodes the string with metadata
const encoded = msg('Hello, world!');
console.log(encoded); // "Hello, world!:eyIkX2hhc2giOiJkMjA3MDliZGExNjNlZmM2In0="
// useMessages() decodes and translates
const m = useMessages();
const translated = m(encoded); // "Hello, world!" in user's language
```
Encoded strings from [`msg`](/docs/react/api/strings/msg) cannot be used directly - they must be decoded with [`useMessages`](/docs/react/api/strings/use-messages).
## Components
Use [`useMessages`](/docs/react/api/strings/use-messages) hook:
```tsx
import { useMessages } from 'gt-react';
const encodedString = msg('Hello, world!');
function MyComponent() {
const m = useMessages();
return {m(encodedString)}
;
}
```
## Getting original strings with decodeMsg
Sometimes you need to access the original string without translation, such as for logging, debugging, or comparisons. Use [`decodeMsg`](/docs/react/api/strings/msg) to extract the original text:
```tsx
import { decodeMsg } from 'gt-react';
const encoded = msg('Hello, world!');
const original = decodeMsg(encoded); // "Hello, world!" (original)
const translated = m(encoded); // "Hello, world!" (in user's language)
// Useful for logging or debugging
console.log('Original string:', decodeMsg(encoded));
console.log('Translated string:', m(encoded));
```
### Use cases for decodeMsg
- **Development & Debugging**: Log original strings for troubleshooting
- **Fallback Handling**: Use original text when translations fail
- **String Comparisons**: Compare against known original values
- **Analytics**: Track original string usage
```tsx
// Example: Fallback handling
function getDisplayText(encodedStr) {
const m = useMessages();
try {
return m(encodedStr);
} catch (error) {
console.warn('Translation failed, using original:', decodeMsg(encodedStr));
return decodeMsg(encodedStr);
}
}
```
## Using variables
For strings with dynamic content, use placeholders and pass variables:
```tsx
// Mark string with variables
const items = 100;
export const pricing = [
{
name: 'Basic',
price: 100,
description: msg('The basic plan includes {items} items', { items })
}
];
```
```tsx
// Use in component
function PricingCard() {
const m = useMessages();
return (
{pricing[0].name}
{m(pricing[0].description)}
);
}
```
### ICU message format
For advanced formatting, use ICU syntax:
```tsx
const count = 10;
const message = msg('There are {count, plural, =0 {no items} =1 {one item} other {{count} items}} in the cart', { count });
```
Learn more about ICU Message Format in the [Unicode documentation](https://unicode-org.github.io/icu/userguide/format_parse/messages/).
## Examples
### Navigation configuration
```tsx
// config/navigation.ts
import { msg } from 'gt-react';
export const mainNav = [
{
label: msg('Home'),
href: '/',
icon: 'home'
},
{
label: msg('Products'),
href: '/products',
icon: 'package'
},
{
label: msg('About Us'),
href: '/about',
icon: 'info'
}
];
export const footerLinks = [
{
title: msg('Company'),
links: [
{ label: msg('About'), href: '/about' },
{ label: msg('Careers'), href: '/careers' },
{ label: msg('Contact'), href: '/contact' }
]
},
{
title: msg('Support'),
links: [
{ label: msg('Help Center'), href: '/help' },
{ label: msg('Documentation'), href: '/docs' },
{ label: msg('API Reference'), href: '/api' }
]
}
];
```
```tsx
// components/Navigation.tsx
import { useMessages } from 'gt-react';
import { mainNav } from '../config/navigation';
function Navigation() {
const m = useMessages();
return (
{mainNav.map((item) => (
{m(item.label)}
))}
);
}
```
### Form configuration
```tsx
// config/forms.ts
import { msg } from 'gt-react';
export const formMessages = {
placeholders: {
email: msg('Enter your email address'),
password: msg('Enter your password'),
message: msg('Type your message here...')
},
actions: {
send: msg('Send Message'),
save: msg('Save Changes'),
cancel: msg('Cancel')
},
validation: {
required: msg('This field is required'),
email: msg('Please enter a valid email address'),
minLength: msg('Must be at least {min} characters', { min: 8 }),
maxLength: msg('Cannot exceed {max} characters', { max: 100 })
},
success: {
saved: msg('Changes saved successfully'),
sent: msg('Message sent successfully'),
updated: msg('Profile updated')
},
errors: {
network: msg('Network error - please try again'),
server: msg('Server error - please contact support'),
timeout: msg('Request timed out - please try again')
}
};
```
```tsx
// components/ContactForm.tsx
import { useMessages } from 'gt-react';
import { formMessages } from '../config/forms';
function ContactForm() {
const m = useMessages();
const [errors, setErrors] = useState({});
return (
{errors.email && {m(formMessages.validation.email)} }
{m(formMessages.actions.send)}
);
}
```
### Dynamic content generation
```tsx
// utils/productData.ts
import { msg } from 'gt-react';
function mockProducts() {
return [
{ name: 'iPhone 15', company: 'Apple', category: 'Electronics' },
{ name: 'Galaxy S24', company: 'Samsung', category: 'Electronics' }
];
}
export function getProductData() {
const products = mockProducts();
return products.map(product => ({
...product,
description: msg('{name} is a {category} product by {company}', {
name: product.name,
category: product.category,
company: product.company
})
}));
}
```
```tsx
// components/ProductList.tsx
import { useMessages } from 'gt-react';
import { getProductData } from '../utils/productData';
function ProductList() {
const m = useMessages();
const products = getProductData();
return (
{products.map(product => (
{product.name}
{m(product.description)}
))}
);
}
```
## Common issues
### Using encoded strings directly
Never use the output of [`msg`](/docs/react/api/strings/msg) directly:
```tsx
// ❌ Wrong - encoded string used directly
const encoded = msg('Hello, world!');
return {encoded}
; // Shows encoded string, not translation
// ✅ Correct - decode the string first
const encoded = msg('Hello, world!');
const m = useMessages();
return {m(encoded)}
; // Shows proper translation
```
### Dynamic content in msg()
Strings must be known at build time:
```tsx
// ❌ Wrong - dynamic template literal
const name = 'John';
const message = msg(`Hello, ${name}`); // Build time error
// ✅ Correct - use variables
const name = 'John';
const message = msg('Hello, {name}', { name });
```
### Forgetting to decode
Every [`msg`](/docs/react/api/strings/msg) string needs to be decoded:
```tsx
// ❌ Missing decoding
const config = {
title: msg('Dashboard'),
subtitle: msg('Welcome back')
};
// Later in component - forgot to decode
return {config.title} ; // Shows encoded string
// ✅ Correct - decode when using
const m = useMessages();
return {m(config.title)} ; // Shows translated title
```
## Next steps
- [Dictionaries Guide](/docs/react/guides/dictionaries) - Organize translations with structured data
- [Languages Guide](/docs/react/guides/languages) - Configure supported languages
- API References:
- [`msg` Function](/docs/react/api/strings/msg)
# gt-react: General Translation React SDK: Strings
URL: https://generaltranslation.com/en-US/docs/react/guides/strings.mdx
---
title: Strings
description: How to internationalize plain text strings using useGT
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
String translation provides direct access to text translations without JSX, perfect for attributes, object properties, and plain text values. Use [`useGT`](/docs/react/api/strings/use-gt) in React components for string translation.
## Quickstart
```jsx
import { useGT } from 'gt-react';
function MyComponent() {
const gt = useGT();
return (
);
}
```
## When to use string translation
String translation is ideal when you need plain text rather than JSX:
### HTML attributes
```jsx
const gt = useGT();
```
### Object properties
```jsx
const gt = useGT();
const user = {
name: 'John',
role: 'admin',
bio: gt('Experienced software developer with 5 years in React'),
status: gt('Currently available for projects')
};
```
### Configuration & constants
```jsx
const gt = useGT();
const navigationItems = [
{ label: gt('Home'), href: '/' },
{ label: gt('Products'), href: '/products' },
{ label: gt('Contact'), href: '/contact' }
];
```
### When to use T instead
Use the [`` component](/docs/react/api/components/t) for JSX content:
```jsx
// ✅ Use for JSX content
Welcome to our store !
// ✅ Use string translation for plain text
```
## Using variables
### Basic variables
Replace placeholders with dynamic values:
```jsx
const gt = useGT();
const itemCount = 5;
// String with placeholder
const message = gt('You have {count} items in your cart', { count: itemCount });
// Result: "You have 5 items in your cart"
```
### Multiple variables
```jsx
const gt = useGT();
const order = { id: 'ORD-123', total: 99.99, date: '2024-01-15' };
const confirmation = gt(
'Order {orderId} for ${total} was placed on {date}',
{
orderId: order.id,
total: order.total,
date: order.date
}
);
```
### ICU message format
For advanced formatting, use ICU syntax:
```jsx
const gt = useGT();
translate('There are {count, plural, =0 {no items} =1 {one item} other {{count} items}} in the cart', { count: 10 });
```
Learn more about ICU Message Format in the [Unicode documentation](https://unicode-org.github.io/icu/userguide/format_parse/messages/).
## Examples
### Form inputs
```jsx
import { useGT } from 'gt-react';
function ContactForm() {
const gt = useGT();
return (
{gt('Send Message')}
);
}
```
### Navigation menu
```jsx
import { useGT } from 'gt-react';
function Navigation() {
const gt = useGT();
const menuItems = [
{ label: gt('Home'), href: '/', icon: 'home' },
{ label: gt('About Us'), href: '/about', icon: 'info' },
{ label: gt('Services'), href: '/services', icon: 'briefcase' },
{ label: gt('Contact'), href: '/contact', icon: 'mail' }
];
return (
{menuItems.map((item) => (
{item.label}
))}
);
}
```
### Dynamic content factory
```jsx
// utils/productData.js
export function getProductMessages(gt) {
return {
categories: [
{ id: 'electronics', name: gt('Electronics') },
{ id: 'clothing', name: gt('Clothing') },
{ id: 'books', name: gt('Books') }
],
statusMessages: {
available: gt('In stock and ready to ship'),
backordered: gt('Currently backordered - ships in 2-3 weeks'),
discontinued: gt('This item has been discontinued')
},
errors: {
notFound: gt('Product not found'),
outOfStock: gt('Sorry, this item is currently out of stock')
}
};
}
// components/ProductCard.jsx
import { useGT } from 'gt-react';
import { getProductMessages } from '../utils/productData';
function ProductCard({ product }) {
const gt = useGT();
const messages = getProductMessages(gt);
return (
{product.name}
{messages.statusMessages[product.status]}
{messages.categories.find(c => c.id === product.categoryId)?.name}
);
}
```
### Component with document title
```jsx
import { useGT } from 'gt-react';
import { useEffect } from 'react';
function ProductPage() {
const gt = useGT();
useEffect(() => {
document.title = gt('Product Catalog - Find What You Need');
// Update meta description
const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) {
metaDescription.setAttribute('content', gt('Browse our extensive collection of high-quality products'));
}
}, [gt]);
return (
{gt('Featured Products')}
{gt('Check out our latest and most popular items')}
);
}
```
## Common issues
### Dynamic content at runtime
Strings must be known at build time - you cannot translate dynamic content:
```jsx
// ❌ Dynamic content won't work
function MyComponent() {
const [userMessage, setUserMessage] = useState('');
const gt = useGT();
return {gt(userMessage)}
; // This will fail
}
// ✅ Use predefined strings
function MyComponent() {
const [messageType, setMessageType] = useState('welcome');
const gt = useGT();
const messages = {
welcome: gt('Welcome to our app!'),
goodbye: gt('Thanks for visiting!')
};
return {messages[messageType]}
;
}
```
### Hook rules violations
Follow React hook rules when using [`useGT`](/docs/react/api/strings/use-gt):
```jsx
// ❌ Don't call hooks conditionally
function MyComponent({ showMessage }) {
if (showMessage) {
const gt = useGT(); // Hook rule violation
return {gt('Hello!')}
;
}
return null;
}
// ✅ Always call hooks at top level
function MyComponent({ showMessage }) {
const gt = useGT();
if (showMessage) {
return {gt('Hello!')}
;
}
return null;
}
```
For truly dynamic content that needs runtime translation, see the [Dynamic Content Guide](/docs/key-concepts/dynamic-content).
## Next steps
- [Dynamic Content Guide](/docs/key-concepts/dynamic-content) - Handle runtime translation
- [Shared Strings Guide](/docs/react/guides/shared-strings) - Organize reusable translations
- API References:
# gt-react: General Translation React SDK: The T Component
URL: https://generaltranslation.com/en-US/docs/react/guides/t.mdx
---
title: The T Component
description: How to internationalize JSX components using the T component
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
The [`` component](/docs/react/api/components/t) is the primary tool for internationalizing JSX content in your React application. It wraps your JSX elements and automatically translates them based on the user's locale.
**Tip:** With [auto JSX injection](/docs/cli/features/auto-jsx-injection) enabled, the compiler can automatically wrap your JSX in translation components at build time.
You may not need to add `` manually in most cases. Manual `` is still useful when you need fine-grained control, such as setting a specific `id` or `context`.
## Quickstart
Transform any static JSX content by wrapping it with [``](/docs/react/api/components/t):
```jsx
import { T } from 'gt-react';
// Before
function Greeting() {
return Hello, world!
;
}
// After
function Greeting() {
return Hello, world!
;
}
```
For dynamic content within [``](/docs/react/api/components/t), use [Variable Components](/docs/react/guides/variables) and [Branching Components](/docs/react/guides/branches).
## Basic usage
The [`` component](/docs/react/api/components/t) accepts any JSX content as children:
```jsx
// Simple text
Welcome to our app
// HTML elements
Page Title
// Complex nested JSX
Important: Please read carefully.
```
## Configuration options
### Adding context
Provide translation context for ambiguous terms:
```jsx
Click the toast to dismiss
```
## When to use T
Use [``](/docs/react/api/components/t) for **static content only**:
```jsx
// ✅ Static content works
Click here
Welcome to our site
// ❌ Dynamic content breaks
Hello {username}
Today is {new Date()}
// ✅ Use Variable components for dynamic content
Hello {username}
```
Variable and Branching components are designed to work inside [``](/docs/react/api/components/t) for dynamic content.
See [Variable Components](/docs/react/guides/variables) and [Branching Components](/docs/react/guides/branches) guides for details.
## Examples
### Simple elements
```jsx
// Basic text
Hello, world!
// Button with text
Submit Form
// Heading with styling
Welcome
```
### Complex components
```jsx
// Navigation menu
About Us
Contact
// Alert message
Your session expires in 5 minutes
```
### With variables
You can use variable components for localized formatting.
```jsx
// Combining static text with dynamic values
Welcome back, {user.name} !
You have {user.friends.length} friends online
Your birthday is {user.birthday}
Your balance is {user.balance}
```
Learn more about the [`` component](/docs/react/api/components/var) in the [Variable Components Guide](/docs/react/guides/variables).
## Production setup
### Build process
Add translation to your build pipeline:
```json title="package.json"
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
### Development vs production behavior
- **Development**: With a dev API key, translations happen on-demand when components render. You'll see real-time translation as you develop.
- **Production**: All translations are pre-built during the build stage and will be visible once your application is live.
Set your development API key in your environment to enable live translation during development. You can create one in the Dashboard under [API Keys](https://dash.generaltranslation.com/en-US/project/api-keys).
### Privacy considerations
Content in [``](/docs/react/api/components/t) components is sent to the GT API for translation. For sensitive data, use [Variable Components](/docs/react/guides/variables) to keep private information local:
```jsx
// Safe - sensitive data stays local
Welcome back, {username}
```
## How much to wrap in a single ``
Wrap **logical content blocks** — content that a translator would naturally read and translate together.
```jsx
// ✅ Good — related content wrapped together gives translators full context
Welcome to Our Platform
Get started in minutes with our simple setup process.
// ✅ Good — each card is an independent unit
{features.map((feature) => (
{feature.title}
{feature.description}
))}
// ❌ Too narrow — fragments the translation, loses context
Welcome to Our Platform
Get started in minutes with our simple setup process.
// ❌ Too wide — wrapping your entire page makes it harder to maintain
{/* ...hundreds of lines of JSX... */}
```
**Rule of thumb:** if text is visually or semantically related, wrap it in one ``. Only split when content is genuinely independent (e.g., a header vs. a footer).
Wrapping more content in a single `` gives translators better context, which produces more natural translations — some languages restructure sentences or need to reference nearby content.
## Common issues
### Component boundaries
[``](/docs/react/api/components/t) only translates direct children, not content inside other components:
```jsx
// ❌ Wrong - content inside components won't be translated
function MyComponent() {
return This won't be translated
;
}
This will be translated
{/* Content inside won't be translated */}
// ✅ Correct - wrap each component individually
function MyComponent() {
return This will be translated
;
}
This will be translated
```
### Nesting T components
```jsx
// ❌ Don't nest components
Hello world {/* Don't do this */}
```
### Dynamic content errors
The CLI will error on dynamic content in [``](/docs/react/api/components/t). Wrap dynamic values with Variable components:
```jsx
// ❌ Wrong - dynamic content breaks
Hello {username}
// ✅ Correct - use Variable components
Hello {username}
```
See the [Variable Components Guide](/docs/react/guides/variables) for handling dynamic values and the [Branching Components Guide](/docs/react/guides/branches) for conditional content.
## Next steps
**See it in action:** Check out the [`` component basics example app](https://github.com/gt-examples/t-component-basics) for a working demo — [live preview](https://t-component-basics.generaltranslation.dev).
- [Variable Components Guide](/docs/react/guides/variables) - Handle dynamic content within JSX translations
- [Branching Components Guide](/docs/react/guides/branches) - Add conditional logic to your translations
# gt-react: General Translation React SDK: Variable Components
URL: https://generaltranslation.com/en-US/docs/react/guides/variables.mdx
---
title: Variable Components
description: How to use variable components for dynamic content within translations
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Variable components allow you to safely include dynamic content within [``](/docs/react/api/components/t) components. They handle formatting and localization locally without sending data to the translation API, making them perfect for sensitive information like usernames, account numbers, and financial data.
## Available components
- [``](/docs/react/api/components/var): Raw dynamic content without formatting
- [``](/docs/react/api/components/num): Numbers with locale-specific formatting
- [``](/docs/react/api/components/currency): Currency values with symbols and formatting
- [``](/docs/react/api/components/datetime): Dates and times with locale conventions
## Quickstart
Variable components work inside [``](/docs/react/api/components/t) to handle dynamic content:
```jsx
import { T, Var, Num, Currency, DateTime } from 'gt-react';
function UserProfile({ user }) {
return (
Welcome back, {user.name} !
You have {user.itemCount} items.
Balance: {user.balance}
Last login: {user.lastLogin}
);
}
```
## How variable components work
Variable components solve the dynamic content problem by:
1. **Wrapping dynamic values** so they can be used inside [``](/docs/react/api/components/t)
2. **Handling formatting locally** using the browser's built-in i18n APIs
3. **Keeping data private** - content is never sent to the translation API
4. **Providing localization** based on the user's current locale
```jsx
// ❌ This breaks - dynamic content in
Hello {username}
// ✅ This works - dynamic content wrapped
Hello {username}
```
## Component guide
### Var - Raw dynamic content
Use [``](/docs/react/api/components/var) for any dynamic content that doesn't need special formatting:
```jsx
// User information
Hello, {user.name} !
Your account ID is {user.accountId}
// Conditional rendering
Dashboard: {isAdmin ? : }
```
### Num - Formatted numbers
Use [``](/docs/react/api/components/num) for numbers that should follow locale formatting rules:
```jsx
// Basic number formatting
You have {itemCount} items in your cart.
// Standalone usage (equivalent to number.toLocaleString())
{totalItems}
// Custom formatting options
Distance: {distance} km
```
### Currency - Money values
Use [``](/docs/react/api/components/currency) for monetary amounts:
```jsx
// Basic currency formatting (defaults to "USD")
Your total is {total} .
// Different currencies
Price: {price}
// Custom formatting
{roundedAmount}
```
### DateTime - Dates and times
Use [``](/docs/react/api/components/datetime) for dates and times:
```jsx
// Basic date formatting
Order placed on {orderDate}
// Time formatting
Last updated: {timestamp}
// Custom date format
{eventDate}
```
## Privacy and security
### Data stays local
Variable components handle all formatting locally using the browser's [Intl APIs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl). **No dynamic content is sent to the translation API**, making them perfect for:
- User names and personal information
- Account numbers and IDs
- Financial data and balances
- Private timestamps and dates
```jsx
// Safe - sensitive data stays local
Account balance: {balance}
Last login: {lastLoginTime}
```
### Important exception
Be careful with nested [``](/docs/react/api/components/t) components inside variable components:
```jsx
// ⚠️ The inner content WILL be sent for translation
Hello, world! {/* This gets translated */}
{privateData} {/* This stays local */}
```
## Standalone usage
Variable components can be used outside of [``](/docs/react/api/components/t) for pure formatting:
```jsx
// These work like their respective .toLocale*() methods
{count} // count.toLocaleString()
{price} // price formatting
{date} // date.toLocaleDateString()
```
## Common issues
### Ignoring localization options
For [``](/docs/react/api/components/currency), make sure to pass the `currency` prop to specify the currency type. This ensures that the correct currency symbol and formatting are used when displaying the value:
```jsx
// ❌ Defaults to USD - may not be what users expect
The item costs {price}
// ✅ Explicitly specify the currency
The item costs {price}
```
Other components also have optional props that allow you to customize the formatting:
```jsx
// Basic formatting
{count} items in stock
// Custom formatting
{percentage} completion rate
// Date formatting
Last updated: {lastUpdate}
```
## Next steps
- [Branching Components Guide](/docs/react/guides/branches) - Add conditional logic to your translations
- [String Translation Guide](/docs/react/guides/strings) - Translate plain text without JSX
- API References:
- [`` Component](/docs/react/api/components/var)
- [`` Component](/docs/react/api/components/num)
- [`` Component](/docs/react/api/components/currency)
# gt-react: General Translation React SDK: GT JSX Data Format
URL: https://generaltranslation.com/en-US/docs/react/reference/gt-jsx.mdx
---
title: GT JSX Data Format
description: Reference for the minified General Translation JSX data format
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
The GT JSX data format is a minified data format used by the General Translation libraries to represent translated UI in your React application.
## Introduction: JSX trees
React represents JSX trees as objects with the following structure:
```ts
type Element = {
type: string;
props: {
children: JSXTree[] | JSXTree;
// ...other props
};
// ...other attributes
};
type JSXTree = Element | string;
```
GT JSX is a compressed version of this JSX tree structure that is used by the General Translation libraries to represent translated UI in your React application.
## Reference
```ts
type Element = {
t?: string; // tag name
c?: (Element | Variable | string)[]; // children
i?: number; // GT ID of the element
d?: {
b?: Record; // branches
t?: "p" | "b"; // branch transformation type (plural or branch)
pl?: string; // placeholder
ti?: string; // title
alt?: string; // alt
arl?: string; // aria-label
arb?: string; // aria-labelledby
ard?: string; // aria-describedby
s?: Record; // style
};
}
type Variable = {
k: string; // key
v?: "v" | "n" | "c" | "d" | "rt"; // type
i?: number; // GT ID
}
type GTJSXTree = Element | Variable | string | (Element | Variable | string)[];
```
## GT JSX: Strings
The simplest form of GT JSX is a string, which represents a static string of text.
For example:
```jsx
Hello, world!
```
Would be represented in GT JSX as:
```ts
"Hello, world!"
```
Arrays of strings are also valid GT JSX:
```ts
["Hello, ", "world!"]
```
## GT JSX: Elements
GT represents JSX `Element` types in two possible ways.
### Variables
The first is a variable, a simple object that contains a key and an optional type. This is used for representing variables that can change at runtime.
```ts
type Variable = {
k: string; // `k` represents key, the name of the variable
v?: ( // represents the type of the variable, if left out is assumed as `v`
"v" | // `v`, a generic variable
"n" | // `n`, a number variable
"c" | // `c`, a currency variable
"d" | // `d`, a datetime variable
"rt" // `rt`, a relative time variable
);
i?: number; // GT ID of the variable
}
```
#### Example 1: Var
```jsx
Hello, {name} !
```
Would be represented in GT JSX as:
```ts
["Hello, ", { k: "_gt_var_1", i: 1 }, "!"]
```
Variables without a name prop are assigned unique internal names based on their GT ID
#### Example 2: Num
```jsx
The count is {count}
```
Would be represented in GT JSX as:
```ts
["The count is ", { k: "count", v: "n", i: 1 }]
```
#### Example 3: With name prop
```jsx
This product costs {amount}
```
Would be represented in GT JSX as:
```ts
["This product costs ", { k: "cost", v: "c", i: 1 }]
```
### Elements
Elements which are not variable are represented using the following data structure:
Note that all of these attributes are optional.
An empty object would represent a translated element in the same position as its original counterpart, with no translatable content among its descendants.
**In practice, `i` is always included.**
```ts
type Element = {
t?: string; // tag name
c?: GTJSXTree | GTJSXTree[]; // children
i?: number; // GT ID of the element
d?: { // data-_gt prop
b?: Record; // branches
t?: "p" | "b"; // branch transformation type (plural or branch)
pl?: string; // placeholder
ti?: string; // title
alt?: string; // alt
arl?: string; // aria-label
arb?: string; // aria-labelledby
ard?: string; // aria-describedby
s?: Record; // style
}
}
```
#### Example 1: Simple tags
```jsx
Hello, world !
```
Would be represented in GT JSX as:
```ts
["Hello, ", { c: "world", i: 1 }, "!"]
```
#### Example 2: Nested, with variables
```jsx
Hello , my name is {name}
```
Would be represented in GT JSX as:
```ts
[
{ t: "b", c: "Hello", i: 1 },
", my name is ",
{
t: "i",
c: { k: "_gt_var_3", i: 3 },
i: 2
}
]
```
#### Example 3: With Plural
```jsx
I have {count} item>}
other={<>I have {count} items>}
/>
```
Would be represented in GT JSX as:
```ts
{
i: 1,
d: {
t: "p",
b: {
one: {
c: ["I have", { k: "_gt_num_4", v: "n", i: 3 }, "item"],
i: 2
},
other: {
c: ["I have", { k: "_gt_num_4", v: "n", i: 3 }, "items"],
i: 2 // note the same ID is used for parallel branches
}
}
}
}
```
### GTJSX type
```ts
type GTJSXTree = Element | Variable | string | (Element | Variable | string)[];
```
## GT IDs
GT IDs are assigned to elements and variables in a JSX tree depth-first and sequentially, starting from 1.
When there are branch components like `` or ``, the same GT IDs are assigned to parallel branches. This is so that if there are more branches in one language than in another (e.g., languages where there are more plural forms), elements with the right props and logic can still be created.
## GT JSX JSON files
Each JSX Tree represents the children of a `` component.
Components are stored together in translation JSON files.
The type of the JSON object stored in these files corresponds to:
```ts
type GTJSXFile = {
[key: string]: GTJSXTree;
}
```
Where `key` is either user-defined or the hash of the original language `GTJSXTree`,
and `GTJSXTree` is the type of the GT JSX tree described above.
### Complete example
The written JSX:
```jsx
Alice's happy customer
```
Would be represented as the following JSX tree:
```ts
[
{
type: "b",
"props": {
"children": "Alice's"
}
},
" happy ",
{
type: "i",
"props": {
"children": "customer"
}
}
]
```
This would be minified into GT JSX as:
```ts
[{ t: "b", c: "Alice's", i: 1 }, " happy ", { t: "i", c: "customer", i: 2 }]
```
When translated into Spanish, the GT JSX would be:
```ts
[{ c: "El cliente", i: 2 }, " feliz ", { c: "de Alice", i: 1 }]
```
It would be stored in a file which looks like:
```json
{ "abc123": [{ "c": "El cliente", "i": 2 }, " feliz ", { "c": "de Alice", "i": 1 }] }
```
`abc123` is the hash of the original English GT JSX tree, not the Spanish translation.
When the Spanish translation is reconciled with the original JSX tree, the following would be produced:
```ts
[
{
type: "i",
"props": {
"children": "El cliente"
}
},
" feliz ",
{
type: "b",
"props": {
"children": "de Alice"
}
}
]
```
Which can then be displayed as the intended UI:
```jsx
<>El cliente feliz de Alice >
```
### Hashes
Hashing algorithm, hash length TBD
### Avoiding hashes at runtime
To avoid computing hashes at runtime, the libraries have an optional fallback mechanism where the user can specify an ID.
```jsx
Hello, world
```
If the ID is present in the translation JSON file, it will be used instead of the hash.
```json
{ "example": "Hello, world" }
```
# gt-react: General Translation React SDK: Internationalize a Mini Shop
URL: https://generaltranslation.com/en-US/docs/react/tutorials/mini-shop.mdx
---
title: Internationalize a Mini Shop
description: A hands-on React tutorial that internationalizes a simple shop using GT React components, hooks, and shared strings
---
Get a small, fully local “mini shop” running and translated — no external services, no routing, no UI frameworks. You’ll use the core GT React features end-to-end and see how they fit together in a simple, realistic UI.
Prerequisites: React, basic JavaScript/TypeScript
What you’ll build
- A single-page “shop” with a product grid and a simple in-memory cart
- Language switcher and shared navigation labels
- Properly internationalized numbers, currency, and pluralization
- Optional: local translation storage for production builds
Links used in this tutorial
- Provider: [``](/docs/react/api/components/gtprovider)
- Components: [``](/docs/react/api/components/t), [``](/docs/react/api/components/var), [``](/docs/react/api/components/num), [``](/docs/react/api/components/currency), [``](/docs/react/api/components/datetime), [``](/docs/react/api/components/branch), [``](/docs/react/api/components/plural), [``](/docs/react/api/components/locale-selector)
- Strings and Shared Strings: [`useGT`](/docs/react/api/strings/use-gt), [`msg`](/docs/react/api/strings/msg), [`useMessages`](/docs/react/api/strings/use-messages)
- Guides: [Variables](/docs/react/guides/variables), [Branching](/docs/react/guides/branches), [Strings](/docs/react/guides/strings), [Local Translation Storage](/docs/react/guides/local-tx), [Changing Languages](/docs/react/guides/languages)
---
## Install and wrap your app
Install packages and wrap your app with the provider.
```bash
npm i gt-react
npm i --save-dev gt
```
```bash
yarn add gt-react
yarn add --dev gt
```
```bash
bun add gt-react
bun add --dev gt
```
```bash
pnpm add gt-react
pnpm add --save-dev gt
```
Optional: Starter Project (Vite)
If you’re starting from scratch, scaffold a Vite React + TypeScript app and then install GT packages:
```bash copy
npm create vite@latest mini-shop -- --template react-ts
cd mini-shop
npm i gt-react
npm i --save-dev gt
```
Then add the files in the sections below (e.g., `src/main.tsx`, `src/App.tsx`, `src/components/*`, `src/data.ts`, `src/nav.ts`).
Create a minimal provider setup.
```tsx title="src/main.tsx" copy
import { StrictMode } from 'react';
import { createRoot } from 'react-dom/client';
import { GTProvider } from 'gt-react'; // See: /docs/react/api/components/gtprovider
import App from './App';
createRoot(document.getElementById('root')!).render(
{/* Enable Spanish and French */}
);
```
Optionally add a `gt.config.json` now (useful later for CI and local storage):
```json title="gt.config.json" copy
{
"defaultLocale": "en",
"locales": ["es", "fr"]
}
```
### Development API keys
You can follow this tutorial without keys (it will render the default language). To see live translations and test language switching in development, add development keys.
Learn more in [Production vs Development](/docs/react/concepts/environments).
```bash title=".env.local" copy
VITE_GT_API_KEY="your-dev-api-key"
VITE_GT_PROJECT_ID="your-project-id"
```
```bash title=".env.local" copy
REACT_APP_GT_API_KEY="your-dev-api-key"
REACT_APP_GT_PROJECT_ID="your-project-id"
```
- Dashboard: https://dash.generaltranslation.com/signup
- Or via CLI:
```bash copy
npx gt auth
```
---
## Seed data and app structure
We’ll hardcode a tiny product array and keep everything client-side. No servers, no routing.
```ts title="src/data.ts" copy
export type Product = {
id: string;
name: string;
description: string;
price: number;
currency: 'USD' | 'EUR';
inStock: boolean;
addedAt: string; // ISO date string
};
export const products: Product[] = [
{
id: 'p-1',
name: 'Wireless Headphones',
description: 'Noise-cancelling over-ear design with 30h battery',
price: 199.99,
currency: 'USD',
inStock: true,
addedAt: new Date().toISOString()
},
{
id: 'p-2',
name: 'Travel Mug',
description: 'Double-wall insulated stainless steel (12oz)',
price: 24.5,
currency: 'USD',
inStock: false,
addedAt: new Date().toISOString()
}
];
```
---
## Shared navigation labels with msg and useMessages
Use [`msg`](/docs/react/api/strings/msg) to mark shared strings in config, then decode them via [`useMessages`](/docs/react/api/strings/use-messages) at render time.
```tsx title="src/nav.ts" copy
import { msg } from 'gt-react'; // See: /docs/react/api/strings/msg
export const nav = [
{ label: msg('Home'), href: '#' },
{ label: msg('Products'), href: '#products' },
{ label: msg('Cart'), href: '#cart' }
];
```
```tsx title="src/components/Header.tsx" copy
import { LocaleSelector, T } from 'gt-react';
import { useMessages } from 'gt-react'; // See: /docs/react/api/strings/use-messages
import { nav } from '../nav';
export default function Header() {
const m = useMessages();
return (
);
}
```
---
## Product cards with T, variables, Branch, and Currency
Use [``](/docs/react/api/components/t) for JSX translation. Wrap dynamic content with variable components like [``](/docs/react/api/components/var), [``](/docs/react/api/components/num), [``](/docs/react/api/components/currency), and [``](/docs/react/api/components/datetime). Handle stock state via [``](/docs/react/api/components/branch).
```tsx title="src/components/ProductCard.tsx" copy
import { T, Var, Num, Currency, DateTime, Branch } from 'gt-react';
import type { Product } from '../data';
export default function ProductCard({ product, onAdd }: { product: Product; onAdd: () => void; }) {
return (
{product.name}
{product.description}
Price: {product.price}
Added: {new Date(product.addedAt)}
In stock}
false={Out of stock
}
/>
Add to cart
);
}
```
---
## Cart with pluralization and totals
Use [``](/docs/react/api/components/plural) to express “X items in cart” and [``](/docs/react/api/components/currency) for totals. Combine with [``](/docs/react/api/components/t), [``](/docs/react/api/components/var), and [``](/docs/react/api/components/num).
```tsx title="src/components/Cart.tsx" copy
import { T, Plural, Var, Num, Currency } from 'gt-react';
import type { Product } from '../data';
export default function Cart({ items, onClear }: { items: Product[]; onClear: () => void; }) {
const total = items.reduce((sum, p) => sum + p.price, 0);
const itemCount = items.length;
return (
Cart
Your cart is empty}
one={You have {itemCount} item
}
other={You have {itemCount} items
}
/>
{items.map((p) => (
{p.name} — {p.price}
))}
Total: {total}
Clear cart
);
}
```
---
## Attributes and placeholders with `useGT`
Use [`useGT`](/docs/react/api/strings/use-gt) for plain string translations like input placeholders and ARIA labels.
```tsx title="src/components/Search.tsx" copy
import { useGT } from 'gt-react';
export default function Search({ onQuery }: { onQuery: (q: string) => void; }) {
const gt = useGT();
return (
onQuery(e.target.value)}
style={{ padding: 8, width: '100%', maxWidth: 320 }}
/>
);
}
```
---
## Put it together
A single-page app with in-memory cart and simple search filter.
```tsx title="src/App.tsx" copy
import { useMemo, useState } from 'react';
import Header from './components/Header';
import Search from './components/Search';
import ProductCard from './components/ProductCard';
import Cart from './components/Cart';
import { products } from './data';
export default function App() {
const [query, setQuery] = useState('');
const [cart, setCart] = useState([]);
const filtered = useMemo(() => {
const q = query.toLowerCase();
return products.filter(p =>
p.name.toLowerCase().includes(q) || p.description.toLowerCase().includes(q)
);
}, [query]);
const items = products.filter(p => cart.includes(p.id));
return (
{filtered.map(p => (
setCart(c => (p.inStock ? [...new Set([...c, p.id])] : c))}
/>
))}
);
}
```
---
## Run locally
Add a simple dev script to your `package.json`, then start the app.
```json title="package.json" copy
{
"scripts": {
"dev": "vite"
}
}
```
Run:
```bash
npm run dev
```
```json title="package.json" copy
{
"scripts": {
"start": "react-scripts start"
}
}
```
Run:
```bash
npm start
```
---
## What you learned
- Translating JSX with [``](/docs/react/api/components/t) and handling dynamic content via [``](/docs/react/api/components/var), [``](/docs/react/api/components/num), [``](/docs/react/api/components/currency), [``](/docs/react/api/components/datetime)
- Expressing conditional content with [``](/docs/react/api/components/branch) and quantities with [``](/docs/react/api/components/plural)
- Translating attributes with [`useGT`](/docs/react/api/strings/use-gt)
- Sharing navigation/config strings using [`msg`](/docs/react/api/strings/msg) and decoding them with [`useMessages`](/docs/react/api/strings/use-messages)
- Switching languages with [``](/docs/react/api/components/locale-selector)
## Next steps
- Explore: [Variables Guide](/docs/react/guides/variables), [Branching Guide](/docs/react/guides/branches), [Strings Guide](/docs/react/guides/strings), [Changing Languages](/docs/react/guides/languages)
# gt-react: General Translation React SDK: Deploy to Production
URL: https://generaltranslation.com/en-US/docs/react/tutorials/quickdeploy.mdx
---
title: Deploy to Production
description: Let's deploy your React app with GT
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Overview
This is a short tutorial to help you deploy your React app with GT.
In total, this should take less than 5 minutes to complete.
We will do this in 3 steps:
Add your production API keys.
Run the `gt configure` command to configure your project.
Add the translate command to your build script.
## Prerequisites
We'll assume that you have already set up your React app with GT.
If you haven't, first set up your project by following the [Quickstart Guide](/docs/react).
## Step 1: Add your production API keys 🔑
To deploy your app to production, you'll need to use a production API key.
From your [dashboard](https://generaltranslation.com/dashboard), go to **API Keys** in the sidebar.
Click on **Create API Key**, and add them to your production environment.
```bash copy
GT_API_KEY="YOUR_GT_API_KEY"
GT_PROJECT_ID="YOUR_GT_PROJECT_ID"
```
**Protect Your API Keys!**
Production keys should **only** ever be used in production.
Likewise, development keys should **only** ever be used in development.
*Never commit your API keys to a public repository!*
## Step 2: Run the `gt configure` command 🔧
If you've previously run the Setup Wizard, you can skip this step.
The setup wizard will have already run the `gt configure` command for you.
Run the `gt configure` command to configure your project.
```bash copy
npx gt configure
```
If you do not want your translations to be hosted on the GT CDN, select "No" when asked.
You will also need to configure the [`loadTranslations`](/docs/react/api/config/load-translations) function.
## Step 3: Add the translate command to your build script 🏗️
The last step is to add the [translate command](/docs/cli/translate) to your build script.
Make sure that the translate command comes before the build command.
```json title="package.json" copy
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
That's it! Now, when you deploy your app to production and run `npm run build`,
your project will be automatically translated and deployed alongside your app.
---
## Next steps
* See the [CLI docs](/docs/cli) for more information on the CLI tool.
* Learn about the different configuration options for the CLI tool [here](/docs/cli/configure).
* Read about the difference between production and development environments [here](/docs/react/concepts/environments).
# react-core-linter: Quickstart
URL: https://generaltranslation.com/en-US/docs/react-core-linter/guides/quickstart.mdx
---
title: Quickstart
description: Quickstart guide for the React Core Linter
---
This package is v0.1.0 and not stable. Subject to breaking changes.
This is an ESLint plugin designed to be used with any of our i18n libraries, `gt-react`, `gt-next`, or `gt-react-native`.
It checks for common implementation errors and offers fixes.
import Video from '@/components/Video';
## Installation
```bash
npm install @generaltranslation/react-core-linter --save-dev
```
## Configuration
Add to your `eslint.config.js`:
```javascript
import gtLint from '@generaltranslation/react-core-linter';
export default [
gtLint.configs.recommended,
];
```
## Rules
- [`static-jsx`](/docs/react-core-linter/rules/static-jsx) - Learn about the static-jsx rule
- [`static-string`](/docs/react-core-linter/rules/static-string) - Learn about the static-string rule
## Next steps
- [Release Notes](/devlog/react-core-linter_v0_1_0) - Release notes
- [The `` Component](/docs/react/guides/t) - How to use the T component
- [Variable Components](/docs/react/guides/variables) - Handle dynamic content in translations
- [String Translation](/docs/react/guides/strings) - Translate plain text strings
# react-core-linter: static-jsx
URL: https://generaltranslation.com/en-US/docs/react-core-linter/rules/static-jsx.mdx
---
title: static-jsx
description: The component must only have static children
---
## Overview
Ensures that dynamic content inside [``](/docs/react/api/components/t) components is wrapped in variable components.
This rule flags dynamic content that appears directly inside [``](/docs/react/api/components/t) components without being wrapped in appropriate variable components like [``](/docs/react/api/components/var) or [``](/docs/react/api/components/branch).
## Auto-fix
Running `eslint --fix` will automatically wrap dynamic content:
- **Ternaries / logical AND** → [``](/docs/react/api/components/branch)
- **Other expressions** → [``](/docs/react/api/components/var)
- **Missing imports** are added automatically
```jsx
// Before fix
Hello {userName}!
{role === "admin" ? "Administrator" : role === "editor" ? "Editor" : "Viewer"}
{isOnline && "Online"}
// After fix
Hello {userName} !
Viewer
```
## Reference
### Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `libs` | `string[]` | `["gt-react", "gt-next", "gt-react-native", "gt-i18n", "@generaltranslation/react-core"]` | Array of library modules to check for translation components |
---
## Configuration
```json
{
"@generaltranslation/react-core-linter/static-jsx": ["error", {
"libs": ["gt-react", "gt-next", "gt-react-native"]
}]
}
```
# react-core-linter: static-string
URL: https://generaltranslation.com/en-US/docs/react-core-linter/rules/static-string.mdx
---
title: static-string
description: Enforce static string usage in translation functions
---
## Overview
Ensures that translation functions like [`gt`](/docs/react/api/strings/use-gt) and [`msg`](/docs/react/api/strings/msg) only accept static strings.
## Reference
### Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| `libs` | `string[]` | `["gt-react", "gt-next", "gt-react-native", "gt-i18n", "@generaltranslation/react-core"]` | Array of library modules to check for translation functions |
---
## Examples
### staticStringRequired
Registration functions can only accept static strings.
#### ❌ Incorrect
```jsx
const gt = useGT();
const dynamicKey = 'Hello';
gt(dynamicKey);
```
#### ✅ Correct
```jsx
const gt = useGT();
gt('Hello');
```
### variableInterpolationRequired
Dynamic string construction is not allowed. Use ICU-style variable interpolation instead.
#### ❌ Incorrect
```jsx
const gt = useGT();
gt(`Hello ${name}!`);
gt('Hello ' + name);
```
#### ✅ Correct
```jsx
const gt = useGT();
gt('Hello {name}!', { name });
```
---
## Configuration
```json
{
"@generaltranslation/react-core-linter/static-string": ["error", {
"libs": ["gt-react", "gt-next", "gt-react-native"]
}]
}
```
# react-native: Production vs Development
URL: https://generaltranslation.com/en-US/docs/react-native/concepts/environments.mdx
---
title: Production vs Development
description: Differences between production and development environments
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Overview
`gt-react-native` behaves differently depending on the environment your React application is running in.
It detects the environment by checking the `NODE_ENV` environment variable.
## Production behavior
### Environment variables
In production, the only accepted environment variable is `GT_PROJECT_ID` (or a prefixed version thereof, such as `NEXT_PUBLIC_GT_PROJECT_ID`).
If an API key is provided as an environment variable, `gt-react-native` will throw an error. This is to prevent API keys from being exposed to the client.
### Translation loading behavior
In production, the `gt-react-native` provider will attempt to load translations from the General Translation CDN, by default.
If you have configured custom translation loading behavior, such as local translations, via the `loadTranslations` function `gt-react-native` will use that instead.
Translation hot reloading is disabled since it is in production.
## Development behavior
### Environment variables
Since development is local and not exposed to foreign users, `gt-react-native` will accept any General Translation environment variables, even if they are prefixed with `NEXT_PUBLIC_`, `VITE_`, (or similar).
### Translation loading behavior
In development, the `gt-react-native` provider will first attempt to load translations in the same way as production.
These translations are loaded into memory.
When rendering a component (that uses `useGT`, ``, or `useTranslations`) in a language different than the default, the `gt-react-native` provider will do the following:
1. If it detects a valid, stored translation for the given content, it will render the translation.
2. If no translation is found, it will attempt to dynamically translate the content via the General Translation API.
3. After translating, the translation will be rendered, and stored in memory for future use.
4. If the translation times out, it will fallback and render the original content.
Our API also internally caches development translations for a short period of time, so if the same translation is requested again, it will be served from cache.
These translations are isolated at the project level, so they will not be mixed up with translations from other projects.
Additionally, the cache is unique to development sessions, so cached translations will not be used in production.
`gt-react-native` will detect changes to components that use `useGT`, ``, or `useTranslations` and will dynamically translate the modified content via our API.
## Production vs development API keys [#api-keys]
To help distinguish between the production and development behavior of `gt-react-native`, we have the concept of "Production API Keys" and "Development API Keys".
### Production API keys
Production API keys are API keys beginning with `gtx-api-`.
When a Production API key is provided, `gt-react-native` will behave as described in the [Production Behavior](#production-behavior) section.
This means that if you are running your React application in development mode, and you provide a Production API key, `gt-react-native` will behave as if you are in production.
Translation hot reloading will be disabled, and components without translations will render the original content.
Other than this behavior, `gt-react-native` will not utilize the Production API key in any way.
The reason why we ask you to create a separate, production API key when shipping to production is because the CLI tool only accesses Production API keys.
The CLI tool will apply billing and rate-limiting using the "production" category.
### Development API keys
Development API keys are API keys beginning with `gtx-dev-`.
When a Development API key is provided, `gt-react-native` will behave as described in the [Development Behavior](#development-behavior) section.
When using a Development API key, billing and rate-limiting will be applied using the "development" category.
Translations created with a Development API key will not be stored, and will not be available for use in production.
The purpose of development translations is to allow you to test your application before shipping to production.
# react-native: Standalone i18n
URL: https://generaltranslation.com/en-US/docs/react-native/concepts/stand-alone.mdx
---
title: Standalone i18n
description: How to use gt-react as a standalone i18n library
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Overview
`gt-react-native` has feature parity with many other i18n libraries.
This means that you can use `gt-react-native` as a standalone i18n library, without using the General Translation platform.
To do this, don't provide any environment variables such as `GT_API_KEY` or `GT_PROJECT_ID`.
See our [migration guide](/docs/react-native/guides/migration) for more information on how to migrate from another i18n library to `gt-react-native`.
## Tradeoffs
Using `gt-react-native` as a standalone i18n library has some tradeoffs.
### Manual translation
You will need to manually translate your app. If you use our platform, we automatically translate your app for you.
If your project only uses [dictionaries](/docs/react-native/guides/dictionaries) with the `useTranslations` function,
you'll need to manually translate your dictionaries, as you would with any other i18n library.
Make sure you load your translated dictionaries with the [`loadDictionary`](/docs/react-native/api/config/load-dictionary) function.
---
### Manual string translation
If your project is using inline translations with the [``](/docs/react-native/guides/t) component
or the [`useGT`](/docs/react-native/guides/strings) functions,
you'll also need to manually translate your strings.
Since there are no keys with inline translations, the CLI tool has a command: [`gt generate`](/docs/cli/generate)
which will automatically generate template files for your project. You'll just need to edit the template files with your translations for each language.
Make sure you load your translated strings with the [`loadTranslations`](/docs/react-native/api/config/load-translations) function.
### No development translations
# react-native: Branching Components
URL: https://generaltranslation.com/en-US/docs/react-native/guides/branches.mdx
---
title: Branching Components
description: How to use branching components for conditional content within translations
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Branching components enable conditional content rendering within [``](/docs/react-native/api/components/t) components. They handle dynamic logic like if/else statements and pluralization rules while ensuring all content variations can be properly translated.
## Available components
- [``](/docs/react-native/api/components/branch): Conditional content based on values or states
- [``](/docs/react-native/api/components/plural): Automatic pluralization using locale-specific rules
## Quickstart
Branching components work inside [``](/docs/react-native/api/components/t) to handle conditional logic:
```jsx
import { T, Branch, Plural, Num, Var } from 'gt-react-native';
function NotificationPanel({ user, messageCount }) {
return (
{user.name} is currently online}
away={{user.name} is away
}
>
{user.name} status unknown
You have {messageCount} message}
other={You have {messageCount} messages
}
/>
);
}
```
## How branching components work
Branching components solve conditional rendering within translations by:
1. **Replacing ternary operators** and conditional logic inside [``](/docs/react-native/api/components/t)
2. **Providing fallback content** when conditions don't match expected values
3. **Enabling translation** of all possible content variations
4. **Following locale rules** for pluralization automatically
```jsx
// ❌ This breaks - conditional logic in
{isActive ? 'User is active' : 'User is inactive'}
// ✅ This works - conditional logic with branching
User is active}
false={User is inactive
}
/>
```
## Component guide
### Branch - Conditional content
Use [``](/docs/react-native/api/components/branch) for any conditional rendering based on values or states:
```jsx
// User status display
Administrator Dashboard}
user={User Dashboard
}
guest={Guest Access
}
>
Access level unknown
// Boolean conditions
Welcome back!}
false={Please log in
}
/>
// Subscription tiers
Upgrade to unlock premium features}
premium={Enjoy your premium experience
}
enterprise={Contact support for enterprise solutions
}
>
Subscription status unavailable
```
### Plural - Smart pluralization
Use [``](/docs/react-native/api/components/plural) for content that changes based on quantity:
```jsx
// Basic pluralization
{itemCount} item in cart}
other={{itemCount} items in cart
}
/>
// Zero handling
No new notifications}
one={{notifications} notification
}
other={{notifications} notifications
}
/>
// Complex pluralization (follows Unicode CLDR rules)
Due today}
one={Due in {days} day
}
few={Due in {days} days
}
many={Due in {days} days
}
other={Due in {days} days
}
/>
```
### Combining with variable components
Branching and variable components work together seamlessly:
```jsx
Order {order.id} is pending.
Total: {order.total}
}
shipped={
Order {order.id} shipped on {order.shippedDate}
}
delivered={
Order {order.id} was delivered successfully
}
>
Order status unknown
```
## When to use branching components
### Replace ternary operators
Convert conditional logic for use within [``](/docs/react-native/api/components/t):
```jsx
// ❌ Can't use ternary in
{isActive ? Active user
: Inactive user
}
// ✅ Use Branch instead
Active user}
false={Inactive user
}
/>
```
### Handle multiple conditions
Replace switch statements or multiple if/else conditions:
```jsx
// ❌ Complex conditional logic
{status === 'loading' ? Loading...
:
status === 'error' ? Error occurred
:
status === 'success' ? Success!
:
Unknown status
}
// ✅ Clean branching logic
Loading...}
error={Error occurred
}
success={Success!
}
>
Unknown status
```
### Pluralization rules
Replace manual plural handling:
```jsx
// ❌ Manual pluralization
{count === 1 ? 1 item
: {count} items
}
// ✅ Automatic pluralization
{count} item}
other={{count} items
}
/>
```
## Standalone usage
Branching components can be used outside [``](/docs/react-native/api/components/t) for pure logic without translation:
```jsx
// Pure conditional rendering
}
light={ }
>
// Pure pluralization
}
other={ }
/>
```
## Common issues
### Missing branch keys
Always provide fallback content for unmatched values:
```jsx
// ❌ No fallback for unexpected values
}
user={ }
// What if userRole is "moderator"?
/>
// ✅ Always include fallback
}
user={ }
>
{/* Fallback for any other value */}
```
### Incomplete plural forms
Provide necessary plural forms for your default locale:
```jsx
// ❌ Missing "other" form
1 item}
// What about 0, 2, 3, etc.?
/>
// ✅ Include required forms
No items}
one={1 item
}
other={{count} items
}
/>
```
### Complex nested logic
Although this works, we recommend keeping branching logic simple and avoid deep nesting:
```jsx
// ❌ Complex nested branching
{/* Hard to read and maintain */}
// ✅ Flatten logic or use multiple components
}
active-offline={ }
inactive-online={ }
>
```
Learn more about pluralization rules in the [Unicode CLDR documentation](https://cldr.unicode.org/index/cldr-spec/plural-rules).
## Next steps
- [String Translation Guide](/docs/react-native/guides/strings) - Translate plain text without JSX
- [Dynamic Content Guide](/docs/key-concepts/dynamic-content) - Handle runtime translation
- API References:
- [`` Component](/docs/react-native/api/components/branch)
# react-native: Dictionaries
URL: https://generaltranslation.com/en-US/docs/react-native/guides/dictionaries.mdx
---
title: Dictionaries
description: How to use traditional dictionary-based translation patterns
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Dictionaries provide a traditional approach to organizing translations in nested objects with key-value pairs. While [`` components](/docs/react-native/guides/t) are the recommended approach, dictionaries can be useful for migration from other i18n libraries or when you prefer centralized translation storage.
**Recommendation:** Use [`` components](/docs/react-native/guides/t) for new projects. Dictionaries are supported primarily for migration and compatibility with existing translation workflows.
## Dictionary vs component translation
### Dictionary pattern
```tsx
// dictionary.ts
export default {
greetings: {
hello: 'Hello, world!',
welcome: 'Welcome, {name}!'
}
};
// Component usage
function MyComponent() {
const t = useTranslations();
return {t('greetings.hello')}
;
}
```
### Component pattern
```tsx
// Direct component usage - recommended
function MyComponent() {
return Hello, world!
;
}
```
## Trade-offs
### Dictionary advantages
- **Centralized storage** - All translations in one place
- **Industry standard** - Familiar pattern from other i18n libraries
- **Migration friendly** - Easy to port existing translations
### Dictionary disadvantages
- **Complexity** - More setup and configuration required
- **Maintainability** - Content separated from usage makes updates harder
- **Debuggability** - Harder to trace translations back to components
- **Readability** - Keys don't show actual content
## Quickstart
### Step 1: Create dictionary
Create a dictionary file in your project root or `src` directory:
```ts title="dictionary.ts"
const dictionary = {
greetings: {
hello: 'Hello, world!',
welcome: 'Welcome to our app!'
},
navigation: {
home: 'Home',
about: 'About',
contact: 'Contact'
}
};
export default dictionary;
```
Or use JSON format:
```json title="dictionary.json"
{
"greetings": {
"hello": "Hello, world!",
"welcome": "Welcome to our app!"
},
"navigation": {
"home": "Home",
"about": "About",
"contact": "Contact"
}
}
```
Then you pass it to your [``](/docs/react-native/api/components/gtprovider) component:
```jsx title="index.js" copy
import dictionary from "./dictionary.js";
import config from "./gt.config.json";
createRoot(document.getElementById("root")!).render(
{/* [!code highlight] */}
);
```
### Step 2: Use in components
The [`useTranslations`](/docs/react-native/api/dictionary/use-translations) hook lets you access dictionary entries:
```tsx
import { useTranslations } from 'gt-react-native';
function MyComponent() {
const t = useTranslations();
return (
{t('greetings.hello')}
{t('greetings.welcome')}
);
}
```
## Using variables
Add variables to dictionary entries using `{variable}` syntax:
```ts title="dictionary.ts"
const dictionary = {
user: {
greeting: 'Hello, {name}!',
itemCount: 'You have {count} items',
orderTotal: 'Total: ${amount}'
}
};
```
```tsx
function UserDashboard() {
const t = useTranslations();
return (
{t('user.greeting', { name: 'Alice' })}
{t('user.itemCount', { count: 5 })}
{t('user.orderTotal', { amount: 99.99 })}
);
}
```
## Using prefixes
Scope dictionary access to specific sections using prefixes:
```ts title="dictionary.ts"
const dictionary = {
dashboard: {
header: {
welcome: 'Welcome back!',
lastLogin: 'Last login: {date}'
},
stats: {
totalUsers: 'Total Users: {count}',
activeUsers: 'Active Users: {count}'
}
}
};
```
```tsx
function DashboardHeader() {
// Prefix limits access to 'dashboard.header'
const t = useTranslations('dashboard.header');
return (
);
}
function DashboardStats() {
// Different prefix for stats section
const t = useTranslations('dashboard.stats');
return (
{t('totalUsers', { count: 1000 })}
{/* -> dashboard.stats.totalUsers */}
{t('activeUsers', { count: 150 })}
{/* -> dashboard.stats.activeUsers */}
);
}
```
## Multiple language support
### Automatic translation (recommended)
Most users should use [`loadTranslations`](/docs/react-native/api/config/load-translations) to automatically generate translations from your base dictionary:
```ts title="dictionary.ts"
const dictionary = {
common: {
save: 'Save',
cancel: 'Cancel',
delete: 'Delete'
},
forms: {
required: 'This field is required',
email: 'Please enter a valid email'
}
};
export default dictionary;
```
Then create a `loadTranslations` function to load generated translation files:
```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
const translations = await import(`./_gt/${locale}.json`);
return translations.default;
}
```
Pass it to your ``:
```tsx title="src/index.tsx"
import loadTranslations from './loadTranslations';
import dictionary from './dictionary';
createRoot(document.getElementById("root")!).render(
);
```
GT automatically generates translations for other languages based on your base dictionary. Run `npx gt translate` to generate translations for all configured languages.
### Manual translation files (migration)
For migration from other i18n libraries or manual translation management, use [`loadDictionary`](/docs/react-native/api/config/load-dictionary):
```ts title="src/loadDictionary.ts"
export default async function loadDictionary(locale: string) {
const translations = await import(`../public/locales/${locale}.json`);
return translations.default;
}
```
This loads JSON translation files from your `public/locales/` directory:
**Choose the right approach:** Use [`loadTranslations`](/docs/react-native/api/config/load-translations) for new projects with automatic translation generation, or [`loadDictionary`](/docs/react-native/api/config/load-dictionary) when migrating existing translation files.
## Production setup
### Build process
Add translation to your build pipeline:
```json title="package.json"
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
### Development vs production behavior
- **Development**: Dictionary entries translated on-demand with dev API key
- **Production**: All dictionary translations pre-built during build step
## Combining with components
Dictionaries and [`` components](/docs/react-native/guides/t) can work together:
```tsx
function MixedApproach() {
const t = useTranslations();
return (
{/* Dictionary for simple strings */}
{t('page.title')}
{/* T component for complex JSX */}
This is a complex message with links .
{/* Dictionary for form labels */}
{t('forms.email')}
);
}
```
## Next steps
**See it in action:** Check out the [dictionary pattern example app](https://github.com/gt-examples/dictionary-pattern) for a working demo — [live preview](https://dictionary-pattern.generaltranslation.dev).
- [Languages Guide](/docs/react-native/guides/languages) - Configure supported languages and locale settings
- [Dynamic Content Guide](/docs/key-concepts/dynamic-content) - Handle runtime translation needs
- API References:
- [`useTranslations` Hook](/docs/react-native/api/dictionary/use-translations)
# react-native: Changing Languages
URL: https://generaltranslation.com/en-US/docs/react-native/guides/languages.mdx
---
title: Changing Languages
description: How to configure and switch between languages in your React Native app
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Language switching allows users to change their preferred locale for your application's content. GT React Native provides several approaches from simple programmatic switching to pre-built UI components for custom language selectors.
## Available methods
- **Programmatic**: [`useSetLocale`](/docs/react-native/api/helpers/use-set-locale) hook for custom controls
- **Pre-built UI**: [``](/docs/react-native/api/components/locale-selector) component with dropdown
- **Custom UI**: [`useLocaleSelector`](/docs/react-native/api/helpers/use-locale-selector) hook for building custom selectors
## Using the `useSetLocale` hook
The [`useSetLocale`](/docs/react-native/api/helpers/use-set-locale) hook allows you to change the language of your app:
```tsx
import { useSetLocale } from 'gt-react-native';
export default function MyComponent() {
const setLocale = useSetLocale();
return setLocale('en')}>Set Locale ;
}
```
Simply provide the locale you want to change to as the argument to the function returned by the hook.
## Using the `` component
The [``](/docs/react-native/api/components/locale-selector) component provides a ready-to-use dropdown that automatically shows all configured locales:
```tsx
import { LocaleSelector } from 'gt-react-native';
export default function MyComponent() {
return ;
}
```
This component automatically:
- Shows all configured locales for your project
- Displays locales in their native language names
- Handles the switching logic
- Maintains current selection state
## Using the `useLocaleSelector` hook
If you want to build your own custom locale selector component, use [`useLocaleSelector`](/docs/react-native/api/helpers/use-locale-selector):
```tsx
import { useLocaleSelector } from 'gt-react-native';
function CustomLocaleSelector() {
const {
locale, // Current active locale (e.g., 'en', 'es')
locales, // Array of locales your project supports ['en', 'es', 'fr']
setLocale, // Function to change the locale: setLocale('es')
getLocaleProperties // Function to get display info for a locale
} = useLocaleSelector();
if (!locales?.length) return null;
return (
setLocale(e.target.value)}
>
{locales.map((loc) => {
const props = getLocaleProperties(loc);
return (
{props.nativeNameWithRegionCode} {/* e.g., "English (US)", "Español (ES)" */}
);
})}
);
}
```
## Important notes
### GTProvider requirement
Language switching components must be used within a [``](/docs/react-native/api/components/gtprovider):
```tsx
// ✅ Correct
// ❌ Wrong - outside provider
```
## Next steps
- [Dynamic Content Guide](/docs/key-concepts/dynamic-content) - Runtime content translation
- API References:
- [`useSetLocale` Hook](/docs/react-native/api/helpers/use-set-locale)
- [`` Component](/docs/react-native/api/components/locale-selector)
- [`useLocaleSelector` Hook](/docs/react-native/api/helpers/use-locale-selector)
# react-native: Local Translation Storage
URL: https://generaltranslation.com/en-US/docs/react-native/guides/local-tx.mdx
---
title: Local Translation Storage
description: Store translations in your app bundle instead of using a CDN
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## What are local translations?
Local translations are stored in your app's bundle, as opposed to being fetched from a CDN (Content Distribution Network). When you add the `gt translate` command to your build process, this generates translations in JSON format. The final step is getting these translations into your app where they can be used.
There are two ways to do this:
1. **In your app's bundle** (local): Save translations to your app's bundle after generation
2. **In a CDN** (default): Fetch translations from a CDN at runtime
By default, `gt-react-native` fetches translations from the General Translation CDN. When translating your app using our API, translations are automatically saved to our CDN.
**Default behavior:** GT uses CDN storage by default. Only switch to local storage if you need the specific benefits it provides.
## Trade-offs
### Benefits of local translations
- **Faster load times**: Local translations are served directly from your app, loading faster than translations served from a CDN
- **No reliance on external services**: Your app's ability to load translations isn't dependent on CDN uptime. If translations aren't found for a locale, the app automatically falls back to the default language
- **Works offline**: Translations are bundled with your app
### Drawbacks of local translations
- **Increased bundle size**: Local translations increase your app's bundle size, potentially making the app slower to load initially
- **Content management**: To edit a translation, you must redeploy your app with the new translation every time you make changes
## Setup
### Step 1: Create load function
Add a `loadTranslations.[js|ts]` file under `./src` with the following content:
```ts title="src/loadTranslations.ts"
export default async function loadTranslations(locale: string) {
const t = await import(`./_gt/${locale}.json`);
return t.default;
}
```
### Step 2: Configure GTProvider
Pass `loadTranslations` as a prop to the [``](/docs/react-native/api/components/gtprovider) component:
```tsx title="src/App.tsx"
import { GTProvider } from 'gt-react-native';
import loadTranslations from './loadTranslations';
export default function App() {
return (
);
}
```
### Step 3: Configure CLI
Run the configuration command and select local storage:
```bash
npx gt configure
```
When prompted:
- **Save to CDN?** Select "No"
- **Translation directory:** The CLI will automatically use `./src/_gt`
Alternatively, you can manually configure the `gt.config.json` file to use local translations. See the [CLI Configuration docs](/docs/cli/reference/config) for more information.
### Step 4: Generate translations
Now when you run the translate command, translations will be automatically downloaded and included in your codebase:
```bash
npx gt translate
```
Translations will be stored in `src/_gt/` and bundled with your app.
## Build integration
### React build process
Add translation generation to your build script:
```json
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
### CI/CD pipeline
```yaml
# .github/workflows/deploy.yml
- name: Generate Translations
run: npx gt translate
- name: Build Application
run: npm run build
```
## Common issues
### Missing translation files
Ensure translations are generated before building:
```bash
# ❌ Build without translations
<...YOUR_BUILD_COMMAND...>
# ✅ Generate translations first
npx gt translate && <...YOUR_BUILD_COMMAND...>
```
### Import path errors
Match your directory structure in the load function:
```ts
// ❌ Wrong path
const t = await import(`../translations/${locale}.json`);
// ✅ Correct path for src/_gt
const t = await import(`./_gt/${locale}.json`);
```
### Large bundle size
Consider code splitting for apps with many languages:
```ts
// Load translations only when needed
export default async function loadTranslations(locale: string) {
// Only load if locale is active
if (locale === getCurrentLocale()) {
const translations = await import(`./_gt/${locale}.json`);
return translations.default;
}
return {};
}
```
Local storage works best for apps with stable translations that don't need frequent updates.
## Next steps
- [Languages Guide](/docs/react-native/guides/languages) - Configure supported languages
# react-native: Migrating
URL: https://generaltranslation.com/en-US/docs/react-native/guides/migration.mdx
---
title: Migrating
description: Learn how to migrate a project to gt-react-native
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Overview
This guide will cover the steps needed to migrate a project that's already using an i18n library to `gt-react-native`.
We'll also provide some tips and suggestions for how to make the migration as smooth as possible.
## Prerequisites
- A project that is currently using another i18n library.
- A basic understanding of the `gt-react-native` library.
## Why migrate?
There are many reasons why you might want to migrate your project to `gt-react-native`.
Here are just a few:
- **No more JSON files:** Never manage translations in JSON files again.
All of your content lives inline with your code, where it belongs.
- **Automatic translations:** Generate high quality, context-aware translations with our CLI tool.
You'll never have to wait for translations again.
- **Experiment in dev:** Easily experiment with translations in development with translation hot-reloading.
## Setup
Install `gt-react-native` and the `gt` CLI tool.
```bash
npm i gt-react-native
npm i gt
```
```bash
yarn add gt-react-native
yarn add --dev gt
```
```bash
bun add gt-react-native
bun add --dev gt
```
```bash
pnpm add gt-react-native
pnpm add --save-dev gt
```
Create a `gt.config.json` file in the root of your project containing a `defaultLocale` property and a `locales` array.
```json title="gt.config.json" copy
{
"defaultLocale": "en",
"locales": ["en", "fr", "es"]
}
```
Add the `` component to the root of your app, and spread the `config` object as props.
```tsx
import { GTProvider } from 'gt-react-native'
import config from './gt.config.json'
```
For more detailed steps, see the [project quickstart](/docs/react-native) guide.
At this point, you have 3 options:
1. Fully migrate your entire project to `gt-react-native`, and remove the old i18n library.
2. Fully migrate your project, but keep using dictionaries from the old i18n library.
2. Keep using the old i18n library for now, and only migrate part of your project to `gt-react-native`.
For more details on each option, see the [migration strategies](#strategies) section.
## Migration strategies [#strategies]
### Option 1: Fully migrate your entire project
This option is the most straightforward, and will also require the most code changes in one go.
After you've set up your project, you'll need to search for all instances of your old i18n library and replace them with `gt-react-native`.
If your app is using React hooks such as `useTranslation`, search for all instances of `useTranslation` in your codebase and replace them with `useGT`.
Then, you'll need to replace all the string keys with their actual string values.
For example, if your old code looks like this:
```json title="dictionary.json"
{
"hello": {
"description": "Hello, world!"
}
}
```
```tsx
export default function MyComponent() {
const { t } = useTranslation()
return {t('hello.description')}
}
```
You'll need to replace it with:
```tsx
export default function MyComponent() {
const { t } = useGT()
return {t('Hello, world!')}
}
// OR
export default function MyComponent() {
return Hello, world!
}
```
Do this for all instances of your old i18n library.
### Option 2: Fully migrate your project, but keep using dictionaries from the old i18n library
Let's say that you want to migrate your project to `gt-react-native`, but you want to keep using dictionaries from the old i18n library
and only use GT inline features for new content.
In this case, you can do something similar to Option 1:
Find all instances of your old i18n library, such as `useTranslation` hooks, and replace them with `useTranslations` hooks.
The `useTranslations` hook behaves very similarly to `useTranslation` hooks, and you can use it in the same way.
```tsx
import { useTranslation } from 'react-i18next'
export default function MyComponent() {
const { t } = useTranslation()
return {t('hello.description')}
}
```
```tsx
import { useTranslations } from 'gt-react-native'
export default function MyComponent() {
const t = useTranslations()
return {t('hello.description')}
}
```
In terms of configuration, you'll need to create a `dictionary.[js|ts|json]` file in your project root or `src` directory.
Copy the contents of your old dictionary file into this new file, then pass it to the `GTProvider` component.
```tsx
import { GTProvider } from 'gt-react-native'
import dictionary from './dictionary.json'
import config from './gt.config.json'
```
See the [dictionaries](/docs/react-native/guides/dictionaries) guide for more details.
### Option 3: Keep using the old i18n library for now, and only migrate part of your project to `gt-react-native`
This option is the most flexible, and will require the least code changes in one go.
In this case, you can do something similar to Option 2, but only migrate part of your project to `gt-react-native`.
For example, you can keep using the old i18n library for some components, and only use `gt-react-native` for others and for new content.
This option is not recommended, as you will have to manage two different i18n libraries in your project, which may be complex and lead to bugs.
## Migration tips
### 1. Use the `useGT` hook or `` component as much as possible
Wherever possible, we recommend using the `useGT` hook or `` component.
This will make editing your content much easier in the future, and make your codebase much more readable.
### 2. Use the `useTranslations` hook for existing content
The `useTranslations` hook is a great way to keep using your existing dictionaries.
We offer it as a way to make migration easier, but we don't recommend using it for new content.
### 3. Using AI
If you are using AI to help you migrate your project, we have a `LLMs.txt` and `LLMs-full.txt` available at:
- [LLMs.txt](/llms.txt)
- [LLMs-full.txt](/llms-full.txt)
These files contain the full content of these docs, so your AI tool will have access to all the information it needs to help you migrate your project.
# react-native: Shared Strings
URL: https://generaltranslation.com/en-US/docs/react-native/guides/shared-strings.mdx
---
title: Shared Strings
description: How to internationalize strings used across multiple components and files
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Shared strings are text values used in multiple places throughout your application - like navigation labels, form messages, or configuration data. Instead of duplicating translation logic everywhere, use [`msg`](/docs/react-native/api/strings/msg) to mark strings for translation and [`useMessages`](/docs/react-native/api/strings/use-messages) to decode them.
## The problem with shared content
Consider this navigation configuration used across your app:
```tsx
// navData.ts
export const navData = [
{
label: 'Home',
description: 'The home page',
href: '/'
},
{
label: 'About',
description: 'Information about the company',
href: '/about'
}
];
```
To internationalize this, you'd typically need to:
1. Convert it to a function that accepts a translation function
2. Update every usage to call the function with `t`
3. Manage the complexity across your codebase
This creates maintenance overhead and makes your code harder to read. The [`msg`](/docs/react-native/api/strings/msg) function solves this by letting you mark strings for translation in-place, then decode them when needed.
## Quickstart
Use [`msg`](/docs/react-native/api/strings/msg) to mark strings and [`useMessages`](/docs/react-native/api/strings/use-messages) to decode them:
```tsx
// navData.ts - Mark strings for translation
import { msg } from 'gt-react-native';
export const navData = [
{
label: msg('Home'),
description: msg('The home page'),
href: '/'
},
{
label: msg('About'),
description: msg('Information about the company'),
href: '/about'
}
];
```
```tsx
// Component usage - Decode marked strings
import { useMessages } from 'gt-react-native';
import { navData } from './navData';
function Navigation() {
const m = useMessages();
return (
{navData.map((item) => (
{m(item.label)}
))}
);
}
```
## How shared strings work
The shared string system works in two phases:
1. **Mark Phase**: [`msg`](/docs/react-native/api/strings/msg) encodes strings with translation metadata
2. **Decode Phase**: [`useMessages`](/docs/react-native/api/strings/use-messages) decodes and translates the strings
```tsx
// msg() encodes the string with metadata
const encoded = msg('Hello, world!');
console.log(encoded); // "Hello, world!:eyIkX2hhc2giOiJkMjA3MDliZGExNjNlZmM2In0="
// useMessages() decodes and translates
const m = useMessages();
const translated = m(encoded); // "Hello, world!" in user's language
```
Encoded strings from [`msg`](/docs/react-native/api/strings/msg) cannot be used directly - they must be decoded with [`useMessages`](/docs/react-native/api/strings/use-messages).
## Components
Use [`useMessages`](/docs/react-native/api/strings/use-messages) hook:
```tsx
import { useMessages } from 'gt-react-native';
const encodedString = msg('Hello, world!');
function MyComponent() {
const m = useMessages();
return {m(encodedString)}
;
}
```
## Getting original strings with decodeMsg
Sometimes you need to access the original string without translation, such as for logging, debugging, or comparisons. Use [`decodeMsg`](/docs/react-native/api/strings/msg) to extract the original text:
```tsx
import { decodeMsg } from 'gt-react-native';
const encoded = msg('Hello, world!');
const original = decodeMsg(encoded); // "Hello, world!" (original)
const translated = m(encoded); // "Hello, world!" (in user's language)
// Useful for logging or debugging
console.log('Original string:', decodeMsg(encoded));
console.log('Translated string:', m(encoded));
```
### Use cases for decodeMsg
- **Development & Debugging**: Log original strings for troubleshooting
- **Fallback Handling**: Use original text when translations fail
- **String Comparisons**: Compare against known original values
- **Analytics**: Track original string usage
```tsx
// Example: Fallback handling
function getDisplayText(encodedStr) {
const m = useMessages();
try {
return m(encodedStr);
} catch (error) {
console.warn('Translation failed, using original:', decodeMsg(encodedStr));
return decodeMsg(encodedStr);
}
}
```
## Using variables
For strings with dynamic content, use placeholders and pass variables:
```tsx
// Mark string with variables
const items = 100;
export const pricing = [
{
name: 'Basic',
price: 100,
description: msg('The basic plan includes {items} items', { items })
}
];
```
```tsx
// Use in component
function PricingCard() {
const m = useMessages();
return (
{pricing[0].name}
{m(pricing[0].description)}
);
}
```
### ICU message format
For advanced formatting, use ICU syntax:
```tsx
const count = 10;
const message = msg('There are {count, plural, =0 {no items} =1 {one item} other {{count} items}} in the cart', { count });
```
Learn more about ICU Message Format in the [Unicode documentation](https://unicode-org.github.io/icu/userguide/format_parse/messages/).
## Examples
### Navigation configuration
```tsx
// config/navigation.ts
import { msg } from 'gt-react-native';
export const mainNav = [
{
label: msg('Home'),
href: '/',
icon: 'home'
},
{
label: msg('Products'),
href: '/products',
icon: 'package'
},
{
label: msg('About Us'),
href: '/about',
icon: 'info'
}
];
export const footerLinks = [
{
title: msg('Company'),
links: [
{ label: msg('About'), href: '/about' },
{ label: msg('Careers'), href: '/careers' },
{ label: msg('Contact'), href: '/contact' }
]
},
{
title: msg('Support'),
links: [
{ label: msg('Help Center'), href: '/help' },
{ label: msg('Documentation'), href: '/docs' },
{ label: msg('API Reference'), href: '/api' }
]
}
];
```
```tsx
// components/Navigation.tsx
import { useMessages } from 'gt-react-native';
import { mainNav } from '../config/navigation';
function Navigation() {
const m = useMessages();
return (
{mainNav.map((item) => (
{m(item.label)}
))}
);
}
```
### Form configuration
```tsx
// config/forms.ts
import { msg } from 'gt-react-native';
export const formMessages = {
placeholders: {
email: msg('Enter your email address'),
password: msg('Enter your password'),
message: msg('Type your message here...')
},
actions: {
send: msg('Send Message'),
save: msg('Save Changes'),
cancel: msg('Cancel')
},
validation: {
required: msg('This field is required'),
email: msg('Please enter a valid email address'),
minLength: msg('Must be at least {min} characters', { min: 8 }),
maxLength: msg('Cannot exceed {max} characters', { max: 100 })
},
success: {
saved: msg('Changes saved successfully'),
sent: msg('Message sent successfully'),
updated: msg('Profile updated')
},
errors: {
network: msg('Network error - please try again'),
server: msg('Server error - please contact support'),
timeout: msg('Request timed out - please try again')
}
};
```
```tsx
// components/ContactForm.tsx
import { useMessages } from 'gt-react-native';
import { formMessages } from '../config/forms';
function ContactForm() {
const m = useMessages();
const [errors, setErrors] = useState({});
return (
{errors.email && {m(formMessages.validation.email)} }
{m(formMessages.actions.send)}
);
}
```
### Dynamic content generation
```tsx
// utils/productData.ts
import { msg } from 'gt-react-native';
function mockProducts() {
return [
{ name: 'iPhone 15', company: 'Apple', category: 'Electronics' },
{ name: 'Galaxy S24', company: 'Samsung', category: 'Electronics' }
];
}
export function getProductData() {
const products = mockProducts();
return products.map(product => ({
...product,
description: msg('{name} is a {category} product by {company}', {
name: product.name,
category: product.category,
company: product.company
})
}));
}
```
```tsx
// components/ProductList.tsx
import { useMessages } from 'gt-react-native';
import { getProductData } from '../utils/productData';
function ProductList() {
const m = useMessages();
const products = getProductData();
return (
{products.map(product => (
{product.name}
{m(product.description)}
))}
);
}
```
## Common issues
### Using encoded strings directly
Never use the output of [`msg`](/docs/react-native/api/strings/msg) directly:
```tsx
// ❌ Wrong - encoded string used directly
const encoded = msg('Hello, world!');
return {encoded}
; // Shows encoded string, not translation
// ✅ Correct - decode the string first
const encoded = msg('Hello, world!');
const m = useMessages();
return {m(encoded)}
; // Shows proper translation
```
### Dynamic content in msg()
Strings must be known at build time:
```tsx
// ❌ Wrong - dynamic template literal
const name = 'John';
const message = msg(`Hello, ${name}`); // Build time error
// ✅ Correct - use variables
const name = 'John';
const message = msg('Hello, {name}', { name });
```
### Forgetting to decode
Every [`msg`](/docs/react-native/api/strings/msg) string needs to be decoded:
```tsx
// ❌ Missing decoding
const config = {
title: msg('Dashboard'),
subtitle: msg('Welcome back')
};
// Later in component - forgot to decode
return {config.title} ; // Shows encoded string
// ✅ Correct - decode when using
const m = useMessages();
return {m(config.title)} ; // Shows translated title
```
## Next steps
- [Dictionaries Guide](/docs/react-native/guides/dictionaries) - Organize translations with structured data
- [Languages Guide](/docs/react-native/guides/languages) - Configure supported languages
- API References:
- [`msg` Function](/docs/react-native/api/strings/msg)
# react-native: Strings
URL: https://generaltranslation.com/en-US/docs/react-native/guides/strings.mdx
---
title: Strings
description: How to internationalize plain text strings using useGT
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
String translation provides direct access to text translations without JSX, perfect for attributes, object properties, and plain text values. Use [`useGT`](/docs/react-native/api/strings/use-gt) in React Native components for string translation.
## Quickstart
```jsx
import { useGT } from 'gt-react-native';
function MyComponent() {
const gt = useGT();
return (
);
}
```
## When to use string translation
String translation is ideal when you need plain text rather than JSX:
### HTML attributes
```jsx
const gt = useGT();
```
### Object properties
```jsx
const gt = useGT();
const user = {
name: 'John',
role: 'admin',
bio: gt('Experienced software developer with 5 years in React'),
status: gt('Currently available for projects')
};
```
### Configuration & constants
```jsx
const gt = useGT();
const navigationItems = [
{ label: gt('Home'), href: '/' },
{ label: gt('Products'), href: '/products' },
{ label: gt('Contact'), href: '/contact' }
];
```
### When to use T instead
Use the [`` component](/docs/react-native/api/components/t) for JSX content:
```jsx
// ✅ Use for JSX content
Welcome to our store !
// ✅ Use string translation for plain text
```
## Using variables
### Basic variables
Replace placeholders with dynamic values:
```jsx
const gt = useGT();
const itemCount = 5;
// String with placeholder
const message = gt('You have {count} items in your cart', { count: itemCount });
// Result: "You have 5 items in your cart"
```
### Multiple variables
```jsx
const gt = useGT();
const order = { id: 'ORD-123', total: 99.99, date: '2024-01-15' };
const confirmation = gt(
'Order {orderId} for ${total} was placed on {date}',
{
orderId: order.id,
total: order.total,
date: order.date
}
);
```
### ICU message format
For advanced formatting, use ICU syntax:
```jsx
const gt = useGT();
translate('There are {count, plural, =0 {no items} =1 {one item} other {{count} items}} in the cart', { count: 10 });
```
Learn more about ICU Message Format in the [Unicode documentation](https://unicode-org.github.io/icu/userguide/format_parse/messages/).
## Examples
### Form inputs
```jsx
import { useGT } from 'gt-react-native';
function ContactForm() {
const gt = useGT();
return (
{gt('Send Message')}
);
}
```
### Navigation menu
```jsx
import { useGT } from 'gt-react-native';
function Navigation() {
const gt = useGT();
const menuItems = [
{ label: gt('Home'), href: '/', icon: 'home' },
{ label: gt('About Us'), href: '/about', icon: 'info' },
{ label: gt('Services'), href: '/services', icon: 'briefcase' },
{ label: gt('Contact'), href: '/contact', icon: 'mail' }
];
return (
{menuItems.map((item) => (
{item.label}
))}
);
}
```
### Dynamic content factory
```jsx
// utils/productData.js
export function getProductMessages(gt) {
return {
categories: [
{ id: 'electronics', name: gt('Electronics') },
{ id: 'clothing', name: gt('Clothing') },
{ id: 'books', name: gt('Books') }
],
statusMessages: {
available: gt('In stock and ready to ship'),
backordered: gt('Currently backordered - ships in 2-3 weeks'),
discontinued: gt('This item has been discontinued')
},
errors: {
notFound: gt('Product not found'),
outOfStock: gt('Sorry, this item is currently out of stock')
}
};
}
// components/ProductCard.jsx
import { useGT } from 'gt-react-native';
import { getProductMessages } from '../utils/productData';
function ProductCard({ product }) {
const gt = useGT();
const messages = getProductMessages(gt);
return (
{product.name}
{messages.statusMessages[product.status]}
{messages.categories.find(c => c.id === product.categoryId)?.name}
);
}
```
### Component with document title
```jsx
import { useGT } from 'gt-react-native';
import { useEffect } from 'react';
function ProductPage() {
const gt = useGT();
useEffect(() => {
document.title = gt('Product Catalog - Find What You Need');
// Update meta description
const metaDescription = document.querySelector('meta[name="description"]');
if (metaDescription) {
metaDescription.setAttribute('content', gt('Browse our extensive collection of high-quality products'));
}
}, [gt]);
return (
{gt('Featured Products')}
{gt('Check out our latest and most popular items')}
);
}
```
## Common issues
### Dynamic content at runtime
Strings must be known at build time - you cannot translate dynamic content:
```jsx
// ❌ Dynamic content won't work
function MyComponent() {
const [userMessage, setUserMessage] = useState('');
const gt = useGT();
return {gt(userMessage)}
; // This will fail
}
// ✅ Use predefined strings
function MyComponent() {
const [messageType, setMessageType] = useState('welcome');
const gt = useGT();
const messages = {
welcome: gt('Welcome to our app!'),
goodbye: gt('Thanks for visiting!')
};
return {messages[messageType]}
;
}
```
### Hook rules violations
Follow React hook rules when using [`useGT`](/docs/react-native/api/strings/use-gt):
```jsx
// ❌ Don't call hooks conditionally
function MyComponent({ showMessage }) {
if (showMessage) {
const gt = useGT(); // Hook rule violation
return {gt('Hello!')}
;
}
return null;
}
// ✅ Always call hooks at top level
function MyComponent({ showMessage }) {
const gt = useGT();
if (showMessage) {
return {gt('Hello!')}
;
}
return null;
}
```
For truly dynamic content that needs runtime translation, see the [Dynamic Content Guide](/docs/key-concepts/dynamic-content).
## Next steps
- [Dynamic Content Guide](/docs/key-concepts/dynamic-content) - Handle runtime translation
- [Shared Strings Guide](/docs/react-native/guides/shared-strings) - Organize reusable translations
- API References:
# react-native: The T Component
URL: https://generaltranslation.com/en-US/docs/react-native/guides/t.mdx
---
title: The T Component
description: How to internationalize JSX components using the T component
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
The [`` component](/docs/react-native/api/components/t) is the primary tool for internationalizing JSX content in your React Native application. It wraps your JSX elements and automatically translates them based on the user's locale.
**Tip:** With [auto JSX injection](/docs/cli/features/auto-jsx-injection) enabled, the compiler can automatically wrap your JSX in translation components at build time.
You may not need to add `` manually in most cases. Manual `` is still useful when you need fine-grained control, such as setting a specific `id` or `context`.
## Quickstart
Transform any static JSX content by wrapping it with [``](/docs/react-native/api/components/t):
```jsx
import { T } from 'gt-react-native';
// Before
function Greeting() {
return Hello, world!
;
}
// After
function Greeting() {
return Hello, world!
;
}
```
For dynamic content within [``](/docs/react-native/api/components/t), use [Variable Components](/docs/react-native/guides/variables) and [Branching Components](/docs/react-native/guides/branches).
## Basic usage
The [`` component](/docs/react-native/api/components/t) accepts any JSX content as children:
```jsx
// Simple text
Welcome to our app
// HTML elements
Page Title
// Complex nested JSX
Important: Please read carefully.
```
## Configuration options
### Adding context
Provide translation context for ambiguous terms:
```jsx
Click the toast to dismiss
```
## When to use T
Use [``](/docs/react-native/api/components/t) for **static content only**:
```jsx
// ✅ Static content works
Click here
Welcome to our site
// ❌ Dynamic content breaks
Hello {username}
Today is {new Date()}
// ✅ Use Variable components for dynamic content
Hello {username}
```
Variable and Branching components are designed to work inside [``](/docs/react-native/api/components/t) for dynamic content.
See [Variable Components](/docs/react-native/guides/variables) and [Branching Components](/docs/react-native/guides/branches) guides for details.
## Examples
### Simple elements
```jsx
// Basic text
Hello, world!
// Button with text
Submit Form
// Heading with styling
Welcome
```
### Complex components
```jsx
// Navigation menu
About Us
Contact
// Alert message
Your session expires in 5 minutes
```
### With variables
You can use variable components for localized formatting.
```jsx
// Combining static text with dynamic values
Welcome back, {user.name} !
You have {user.friends.length} friends online
Your birthday is {user.birthday}
Your balance is {user.balance}
```
Learn more about the [`` component](/docs/react-native/api/components/var) in the [Variable Components Guide](/docs/react-native/guides/variables).
## Production setup
### Build process
Add translation to your build pipeline:
```json title="package.json"
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
### Development vs production behavior
- **Development**: With a dev API key, translations happen on-demand when components render. You'll see real-time translation as you develop.
- **Production**: All translations are pre-built during the build stage and will be visible once your application is live.
Set your development API key in your environment to enable live translation during development. You can create one in the Dashboard under [API Keys](https://dash.generaltranslation.com/en-US/project/api-keys).
### Privacy considerations
Content in [``](/docs/react-native/api/components/t) components is sent to the GT API for translation. For sensitive data, use [Variable Components](/docs/react-native/guides/variables) to keep private information local:
```jsx
// Safe - sensitive data stays local
Welcome back, {username}
```
## How much to wrap in a single ``
Wrap **logical content blocks** — content that a translator would naturally read and translate together.
```jsx
// ✅ Good — related content wrapped together gives translators full context
Welcome to Our Platform
Get started in minutes with our simple setup process.
// ✅ Good — each card is an independent unit
{features.map((feature) => (
{feature.title}
{feature.description}
))}
// ❌ Too narrow — fragments the translation, loses context
Welcome to Our Platform
Get started in minutes with our simple setup process.
// ❌ Too wide — wrapping your entire page makes it harder to maintain
{/* ...hundreds of lines of JSX... */}
```
**Rule of thumb:** if text is visually or semantically related, wrap it in one ``. Only split when content is genuinely independent (e.g., a header vs. a footer).
Wrapping more content in a single `` gives translators better context, which produces more natural translations — some languages restructure sentences or need to reference nearby content.
## Common issues
### Component boundaries
[``](/docs/react-native/api/components/t) only translates direct children, not content inside other components:
```jsx
// ❌ Wrong - content inside components won't be translated
function MyComponent() {
return This won't be translated
;
}
This will be translated
{/* Content inside won't be translated */}
// ✅ Correct - wrap each component individually
function MyComponent() {
return This will be translated
;
}
This will be translated
```
### Nesting T components
```jsx
// ❌ Don't nest components
Hello world {/* Don't do this */}
```
### Dynamic content errors
The CLI will error on dynamic content in [``](/docs/react-native/api/components/t). Wrap dynamic values with Variable components:
```jsx
// ❌ Wrong - dynamic content breaks
Hello {username}
// ✅ Correct - use Variable components
Hello {username}
```
See the [Variable Components Guide](/docs/react-native/guides/variables) for handling dynamic values and the [Branching Components Guide](/docs/react-native/guides/branches) for conditional content.
## Next steps
**See it in action:** Check out the [`` component basics example app](https://github.com/gt-examples/t-component-basics) for a working demo — [live preview](https://t-component-basics.generaltranslation.dev).
- [Variable Components Guide](/docs/react-native/guides/variables) - Handle dynamic content within JSX translations
- [Branching Components Guide](/docs/react-native/guides/branches) - Add conditional logic to your translations
# react-native: Variable Components
URL: https://generaltranslation.com/en-US/docs/react-native/guides/variables.mdx
---
title: Variable Components
description: How to use variable components for dynamic content within translations
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
Variable components allow you to safely include dynamic content within [``](/docs/react-native/api/components/t) components. They handle formatting and localization locally without sending data to the translation API, making them perfect for sensitive information like usernames, account numbers, and financial data.
## Available components
- [``](/docs/react-native/api/components/var): Raw dynamic content without formatting
- [``](/docs/react-native/api/components/num): Numbers with locale-specific formatting
- [``](/docs/react-native/api/components/currency): Currency values with symbols and formatting
- [``](/docs/react-native/api/components/datetime): Dates and times with locale conventions
## Quickstart
Variable components work inside [``](/docs/react-native/api/components/t) to handle dynamic content:
```jsx
import { T, Var, Num, Currency, DateTime } from 'gt-react-native';
function UserProfile({ user }) {
return (
Welcome back, {user.name} !
You have {user.itemCount} items.
Balance: {user.balance}
Last login: {user.lastLogin}
);
}
```
## How variable components work
Variable components solve the dynamic content problem by:
1. **Wrapping dynamic values** so they can be used inside [``](/docs/react-native/api/components/t)
2. **Handling formatting locally** using the browser's built-in i18n APIs
3. **Keeping data private** - content is never sent to the translation API
4. **Providing localization** based on the user's current locale
```jsx
// ❌ This breaks - dynamic content in
Hello {username}
// ✅ This works - dynamic content wrapped
Hello {username}
```
## Component guide
### Var - Raw dynamic content
Use [``](/docs/react-native/api/components/var) for any dynamic content that doesn't need special formatting:
```jsx
// User information
Hello, {user.name} !
Your account ID is {user.accountId}
// Conditional rendering
Dashboard: {isAdmin ? : }
```
### Num - Formatted numbers
Use [``](/docs/react-native/api/components/num) for numbers that should follow locale formatting rules:
```jsx
// Basic number formatting
You have {itemCount} items in your cart.
// Standalone usage (equivalent to number.toLocaleString())
{totalItems}
// Custom formatting options
Distance: {distance} km
```
### Currency - Money values
Use [``](/docs/react-native/api/components/currency) for monetary amounts:
```jsx
// Basic currency formatting (defaults to "USD")
Your total is {total} .
// Different currencies
Price: {price}
// Custom formatting
{roundedAmount}
```
### DateTime - Dates and times
Use [``](/docs/react-native/api/components/datetime) for dates and times:
```jsx
// Basic date formatting
Order placed on {orderDate}
// Time formatting
Last updated: {timestamp}
// Custom date format
{eventDate}
```
## Privacy and security
### Data stays local
Variable components handle all formatting locally using the browser's [Intl APIs](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl). **No dynamic content is sent to the translation API**, making them perfect for:
- User names and personal information
- Account numbers and IDs
- Financial data and balances
- Private timestamps and dates
```jsx
// Safe - sensitive data stays local
Account balance: {balance}
Last login: {lastLoginTime}
```
### Important exception
Be careful with nested [``](/docs/react-native/api/components/t) components inside variable components:
```jsx
// ⚠️ The inner content WILL be sent for translation
Hello, world! {/* This gets translated */}
{privateData} {/* This stays local */}
```
## Standalone usage
Variable components can be used outside of [``](/docs/react-native/api/components/t) for pure formatting:
```jsx
// These work like their respective .toLocale*() methods
{count} // count.toLocaleString()
{price} // price formatting
{date} // date.toLocaleDateString()
```
## Common issues
### Ignoring localization options
For [``](/docs/react-native/api/components/currency), make sure to pass the `currency` prop to specify the currency type. This ensures that the correct currency symbol and formatting are used when displaying the value:
```jsx
// ❌ Defaults to USD - may not be what users expect
The item costs {price}
// ✅ Explicitly specify the currency
The item costs {price}
```
Other components also have optional props that allow you to customize the formatting:
```jsx
// Basic formatting
{count} items in stock
// Custom formatting
{percentage} completion rate
// Date formatting
Last updated: {lastUpdate}
```
## Next steps
- [Branching Components Guide](/docs/react-native/guides/branches) - Add conditional logic to your translations
- [String Translation Guide](/docs/react-native/guides/strings) - Translate plain text without JSX
- API References:
- [`` Component](/docs/react-native/api/components/var)
- [`` Component](/docs/react-native/api/components/num)
- [`` Component](/docs/react-native/api/components/currency)
# react-native: GT JSX Data Format
URL: https://generaltranslation.com/en-US/docs/react-native/reference/gt-jsx.mdx
---
title: GT JSX Data Format
description: Reference for the minified General Translation JSX data format
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
The GT JSX data format is a minified data format used by the General Translation libraries to represent translated UI in your React application.
## Introduction: JSX trees
React represents JSX trees as objects with the following structure:
```ts
type Element = {
type: string;
props: {
children: JSXTree[] | JSXTree;
// ...other props
};
// ...other attributes
};
type JSXTree = Element | string;
```
GT JSX is a compressed version of this JSX tree structure that is used by the General Translation libraries to represent translated UI in your React application.
## Reference
```ts
type Element = {
t?: string; // tag name
c?: (Element | Variable | string)[]; // children
i?: number; // GT ID of the element
d?: {
b?: Record; // branches
t?: "p" | "b"; // branch transformation type (plural or branch)
pl?: string; // placeholder
ti?: string; // title
alt?: string; // alt
arl?: string; // aria-label
arb?: string; // aria-labelledby
ard?: string; // aria-describedby
s?: Record; // style
};
}
type Variable = {
k: string; // key
v?: "v" | "n" | "c" | "d" | "rt"; // type
i?: number; // GT ID
}
type GTJSXTree = Element | Variable | string | (Element | Variable | string)[];
```
## GT JSX: Strings
The simplest form of GT JSX is a string, which represents a static string of text.
For example:
```jsx
Hello, world!
```
Would be represented in GT JSX as:
```ts
"Hello, world!"
```
Arrays of strings are also valid GT JSX:
```ts
["Hello, ", "world!"]
```
## GT JSX: Elements
GT represents JSX `Element` types in two possible ways.
### Variables
The first is a variable, a simple object that contains a key and an optional type. This is used for representing variables that can change at runtime.
```ts
type Variable = {
k: string; // `k` represents key, the name of the variable
v?: ( // represents the type of the variable, if left out is assumed as `v`
"v" | // `v`, a generic variable
"n" | // `n`, a number variable
"c" | // `c`, a currency variable
"d" | // `d`, a datetime variable
"rt" // `rt`, a relative time variable
);
i?: number; // GT ID of the variable
}
```
#### Example 1: Var
```jsx
Hello, {name} !
```
Would be represented in GT JSX as:
```ts
["Hello, ", { k: "_gt_var_1", i: 1 }, "!"]
```
Variables without a name prop are assigned unique internal names based on their GT ID
#### Example 2: Num
```jsx
The count is {count}
```
Would be represented in GT JSX as:
```ts
["The count is ", { k: "count", v: "n", i: 1 }]
```
#### Example 3: With name prop
```jsx
This product costs {amount}
```
Would be represented in GT JSX as:
```ts
["This product costs ", { k: "cost", v: "c", i: 1 }]
```
### Elements
Elements which are not variable are represented using the following data structure:
Note that all of these attributes are optional.
An empty object would represent a translated element in the same position as its original counterpart, with no translatable content among its descendants.
**In practice, `i` is always included.**
```ts
type Element = {
t?: string; // tag name
c?: GTJSXTree | GTJSXTree[]; // children
i?: number; // GT ID of the element
d?: { // data-_gt prop
b?: Record; // branches
t?: "p" | "b"; // branch transformation type (plural or branch)
pl?: string; // placeholder
ti?: string; // title
alt?: string; // alt
arl?: string; // aria-label
arb?: string; // aria-labelledby
ard?: string; // aria-describedby
s?: Record; // style
}
}
```
#### Example 1: Simple tags
```jsx
Hello, world !
```
Would be represented in GT JSX as:
```ts
["Hello, ", { c: "world", i: 1 }, "!"]
```
#### Example 2: Nested, with variables
```jsx
Hello , my name is {name}
```
Would be represented in GT JSX as:
```ts
[
{ t: "b", c: "Hello", i: 1 },
", my name is ",
{
t: "i",
c: { k: "_gt_var_3", i: 3 },
i: 2
}
]
```
#### Example 3: With Plural
```jsx
I have {count} item>}
other={<>I have {count} items>}
/>
```
Would be represented in GT JSX as:
```ts
{
i: 1,
d: {
t: "p",
b: {
one: {
c: ["I have", { k: "_gt_num_4", v: "n", i: 3 }, "item"],
i: 2
},
other: {
c: ["I have", { k: "_gt_num_4", v: "n", i: 3 }, "items"],
i: 2 // note the same ID is used for parallel branches
}
}
}
}
```
### GTJSX type
```ts
type GTJSXTree = Element | Variable | string | (Element | Variable | string)[];
```
## GT IDs
GT IDs are assigned to elements and variables in a JSX tree depth-first and sequentially, starting from 1.
When there are branch components like `` or ``, the same GT IDs are assigned to parallel branches. This is so that if there are more branches in one language than in another (e.g., languages where there are more plural forms), elements with the right props and logic can still be created.
## GT JSX JSON files
Each JSX Tree represents the children of a `` component.
Components are stored together in translation JSON files.
The type of the JSON object stored in these files corresponds to:
```ts
type GTJSXFile = {
[key: string]: GTJSXTree;
}
```
Where `key` is either user-defined or the hash of the original language `GTJSXTree`,
and `GTJSXTree` is the type of the GT JSX tree described above.
### Complete example
The written JSX:
```jsx
Alice's happy customer
```
Would be represented as the following JSX tree:
```ts
[
{
type: "b",
"props": {
"children": "Alice's"
}
},
" happy ",
{
type: "i",
"props": {
"children": "customer"
}
}
]
```
This would be minified into GT JSX as:
```ts
[{ t: "b", c: "Alice's", i: 1 }, " happy ", { t: "i", c: "customer", i: 2 }]
```
When translated into Spanish, the GT JSX would be:
```ts
[{ c: "El cliente", i: 2 }, " feliz ", { c: "de Alice", i: 1 }]
```
It would be stored in a file which looks like:
```json
{ "abc123": [{ "c": "El cliente", "i": 2 }, " feliz ", { "c": "de Alice", "i": 1 }] }
```
`abc123` is the hash of the original English GT JSX tree, not the Spanish translation.
When the Spanish translation is reconciled with the original JSX tree, the following would be produced:
```ts
[
{
type: "i",
"props": {
"children": "El cliente"
}
},
" feliz ",
{
type: "b",
"props": {
"children": "de Alice"
}
}
]
```
Which can then be displayed as the intended UI:
```jsx
<>El cliente feliz de Alice >
```
### Hashes
Hashing algorithm, hash length TBD
### Avoiding hashes at runtime
To avoid computing hashes at runtime, the libraries have an optional fallback mechanism where the user can specify an ID.
```jsx
Hello, world
```
If the ID is present in the translation JSON file, it will be used instead of the hash.
```json
{ "example": "Hello, world" }
```
# react-native: Internationalize a Mini Shop
URL: https://generaltranslation.com/en-US/docs/react-native/tutorials/mini-shop.mdx
---
title: Internationalize a Mini Shop
description: A hands-on React Native tutorial that internationalizes a simple shop using GT React Native components, hooks, and shared strings
---
`gt-react-native` is still experimental and may not work for all projects.
Please let us know if you encounter any issues by [opening an issue on GitHub](https://github.com/generaltranslation/gt/issues).
Get a small, fully local "mini shop" running and translated in React Native — no external services, no routing, no UI frameworks beyond Expo. You'll use the core GT React Native features end-to-end and see how they fit together in a simple, realistic mobile UI.
Prerequisites: React Native (Expo), basic JavaScript/TypeScript
What you'll build
- A single-screen "shop" with a product list and a simple in-memory cart
- Language switcher and shared navigation labels
- Properly internationalized numbers, currency, and pluralization
Links used in this tutorial
- Provider: [``](/docs/react-native/api/components/gtprovider)
- Components: [``](/docs/react-native/api/components/t), [``](/docs/react-native/api/components/var), [``](/docs/react-native/api/components/num), [``](/docs/react-native/api/components/currency), [``](/docs/react-native/api/components/datetime), [``](/docs/react-native/api/components/branch), [``](/docs/react-native/api/components/plural), [``](/docs/react-native/api/components/locale-selector)
- Strings and Shared Strings: [`useGT`](/docs/react-native/api/strings/use-gt), [`msg`](/docs/react-native/api/strings/msg), [`useMessages`](/docs/react-native/api/strings/use-messages)
- Guides: [Variables](/docs/react-native/guides/variables), [Branching](/docs/react-native/guides/branches), [Strings](/docs/react-native/guides/strings), [Local Translation Storage](/docs/react-native/guides/local-tx), [Changing Languages](/docs/react-native/guides/languages)
---
## Install and wrap your app
Install packages and wrap your app with the provider.
```bash
npm i gt-react-native
npm i --save-dev gt
```
```bash
yarn add gt-react-native
yarn add --dev gt
```
```bash
bun add gt-react-native
bun add --dev gt
```
```bash
pnpm add gt-react-native
pnpm add --save-dev gt
```
Optional: Starter Project (Expo)
If you're starting from scratch, scaffold an Expo app and then install GT packages:
```bash copy
npx create-expo-app mini-shop --template blank-typescript
cd mini-shop
npm i gt-react-native
npm i --save-dev gt
```
Then add the files in the sections below (e.g., `App.tsx`, `components/*`, `data.ts`, `nav.ts`).
Create a minimal provider setup.
```tsx title="App.tsx" copy
import { GTProvider } from 'gt-react-native';
import Shop from './Shop';
export default function App() {
return (
);
}
```
Optionally add a `gt.config.json` now (useful later for CI and local storage):
```json title="gt.config.json" copy
{
"defaultLocale": "en",
"locales": ["es", "fr"]
}
```
### Development API keys
You can follow this tutorial without keys (it will render the default language). To see live translations and test language switching in development, add development keys.
Learn more in [Production vs Development](/docs/react-native/concepts/environments).
```bash title=".env" copy
EXPO_PUBLIC_GT_API_KEY="your-dev-api-key"
EXPO_PUBLIC_GT_PROJECT_ID="your-project-id"
```
- Dashboard: https://dash.generaltranslation.com/signup
- Or via CLI:
```bash copy
npx gt auth
```
---
## Seed data and app structure
We'll hardcode a tiny product array and keep everything client-side. No servers, no navigation.
```ts title="data.ts" copy
export type Product = {
id: string;
name: string;
description: string;
price: number;
currency: 'USD' | 'EUR';
inStock: boolean;
addedAt: string; // ISO date string
};
export const products: Product[] = [
{
id: 'p-1',
name: 'Wireless Headphones',
description: 'Noise-cancelling over-ear design with 30h battery',
price: 199.99,
currency: 'USD',
inStock: true,
addedAt: new Date().toISOString()
},
{
id: 'p-2',
name: 'Travel Mug',
description: 'Double-wall insulated stainless steel (12oz)',
price: 24.5,
currency: 'USD',
inStock: false,
addedAt: new Date().toISOString()
}
];
```
---
## Shared navigation labels with msg and useMessages
Use [`msg`](/docs/react-native/api/strings/msg) to mark shared strings in config, then decode them via [`useMessages`](/docs/react-native/api/strings/use-messages) at render time.
```tsx title="nav.ts" copy
import { msg } from 'gt-react-native';
export const navItems = [
{ label: msg('Home'), id: 'home' },
{ label: msg('Products'), id: 'products' },
{ label: msg('Cart'), id: 'cart' }
];
```
```tsx title="components/Header.tsx" copy
import { View, Text, StyleSheet } from 'react-native';
import { LocaleSelector, T } from 'gt-react-native';
import { useMessages } from 'gt-react-native';
import { navItems } from '../nav';
export default function Header() {
const m = useMessages();
return (
Mini Shop
{navItems.map(item => (
{m(item.label)}
))}
);
}
const styles = StyleSheet.create({
header: {
paddingVertical: 16,
paddingHorizontal: 12,
borderBottomWidth: 1,
borderBottomColor: '#eee',
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 8,
},
nav: {
flexDirection: 'row',
gap: 12,
marginBottom: 8,
},
navItem: {
fontSize: 14,
color: '#555',
},
});
```
---
## Product cards with T, variables, Branch, and Currency
Use [``](/docs/react-native/api/components/t) for JSX translation. Wrap dynamic content with variable components like [``](/docs/react-native/api/components/var), [``](/docs/react-native/api/components/num), [``](/docs/react-native/api/components/currency), and [``](/docs/react-native/api/components/datetime). Handle stock state via [``](/docs/react-native/api/components/branch).
```tsx title="components/ProductCard.tsx" copy
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { T, Var, Currency, DateTime, Branch } from 'gt-react-native';
import type { Product } from '../data';
export default function ProductCard({ product, onAdd }: { product: Product; onAdd: () => void }) {
return (
{product.name}
{product.description}
Price: {product.price}
Added: {product.addedAt}
In stock}
false={Out of stock }
/>
Add to cart
);
}
const styles = StyleSheet.create({
card: {
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 8,
padding: 12,
marginBottom: 12,
},
name: {
fontSize: 18,
fontWeight: '600',
marginBottom: 4,
},
description: {
fontSize: 14,
color: '#666',
marginBottom: 8,
},
price: {
fontSize: 16,
marginBottom: 4,
},
date: {
fontSize: 12,
color: '#999',
marginBottom: 8,
},
inStock: {
color: 'green',
marginBottom: 8,
},
outOfStock: {
color: 'tomato',
marginBottom: 8,
},
button: {
backgroundColor: '#007AFF',
paddingVertical: 10,
borderRadius: 6,
alignItems: 'center',
},
buttonDisabled: {
backgroundColor: '#ccc',
},
buttonText: {
color: '#fff',
fontWeight: '600',
},
});
```
---
## Cart with pluralization and totals
Use [``](/docs/react-native/api/components/plural) to express "X items in cart" and [``](/docs/react-native/api/components/currency) for totals. Combine with [``](/docs/react-native/api/components/t), [``](/docs/react-native/api/components/var), and [``](/docs/react-native/api/components/num).
```tsx title="components/Cart.tsx" copy
import { View, Text, TouchableOpacity, StyleSheet } from 'react-native';
import { T, Plural, Var, Num, Currency } from 'gt-react-native';
import type { Product } from '../data';
export default function Cart({ items, onClear }: { items: Product[]; onClear: () => void }) {
const total = items.reduce((sum, p) => sum + p.price, 0);
const itemCount = items.length;
return (
Cart
Your cart is empty}
one={You have {itemCount} item }
other={You have {itemCount} items }
/>
{items.map((p) => (
{p.name} — {p.price}
))}
Total: {total}
Clear cart
);
}
const styles = StyleSheet.create({
container: {
borderTopWidth: 1,
borderTopColor: '#eee',
paddingTop: 16,
marginTop: 16,
},
heading: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 8,
},
empty: {
color: '#999',
marginBottom: 8,
},
item: {
fontSize: 14,
marginVertical: 4,
},
total: {
fontSize: 16,
fontWeight: '600',
marginTop: 8,
marginBottom: 12,
},
button: {
backgroundColor: '#FF3B30',
paddingVertical: 10,
borderRadius: 6,
alignItems: 'center',
},
buttonDisabled: {
backgroundColor: '#ccc',
},
buttonText: {
color: '#fff',
fontWeight: '600',
},
});
```
---
## Attributes and placeholders with `useGT`
Use [`useGT`](/docs/react-native/api/strings/use-gt) for plain string translations like input placeholders and accessibility labels.
```tsx title="components/Search.tsx" copy
import { TextInput, StyleSheet } from 'react-native';
import { useGT } from 'gt-react-native';
export default function Search({ onQuery }: { onQuery: (q: string) => void }) {
const gt = useGT();
return (
);
}
const styles = StyleSheet.create({
input: {
borderWidth: 1,
borderColor: '#ddd',
borderRadius: 8,
padding: 10,
fontSize: 16,
},
});
```
---
## Put it together
A single-screen app with in-memory cart and simple search filter.
```tsx title="Shop.tsx" copy
import { useMemo, useState } from 'react';
import { SafeAreaView, ScrollView, View, StyleSheet } from 'react-native';
import Header from './components/Header';
import Search from './components/Search';
import ProductCard from './components/ProductCard';
import Cart from './components/Cart';
import { products } from './data';
export default function Shop() {
const [query, setQuery] = useState('');
const [cart, setCart] = useState([]);
const filtered = useMemo(() => {
const q = query.toLowerCase();
return products.filter(p =>
p.name.toLowerCase().includes(q) || p.description.toLowerCase().includes(q)
);
}, [query]);
const items = products.filter(p => cart.includes(p.id));
return (
{filtered.map(p => (
setCart(c => (p.inStock ? [...new Set([...c, p.id])] : c))}
/>
))}
setCart([])}
/>
);
}
const styles = StyleSheet.create({
safe: {
flex: 1,
backgroundColor: '#fff',
},
scroll: {
padding: 16,
},
searchContainer: {
marginVertical: 12,
},
products: {
gap: 0,
},
});
```
---
## Run locally
Start the Expo dev server:
```bash
npx expo start
```
Then open in the Expo Go app on your phone, or press `i` for iOS simulator / `a` for Android emulator.
---
## What you learned
- Translating JSX with [``](/docs/react-native/api/components/t) and handling dynamic content via [``](/docs/react-native/api/components/var), [``](/docs/react-native/api/components/num), [``](/docs/react-native/api/components/currency), [``](/docs/react-native/api/components/datetime)
- Expressing conditional content with [``](/docs/react-native/api/components/branch) and quantities with [``](/docs/react-native/api/components/plural)
- Translating attributes with [`useGT`](/docs/react-native/api/strings/use-gt)
- Sharing navigation/config strings using [`msg`](/docs/react-native/api/strings/msg) and decoding them with [`useMessages`](/docs/react-native/api/strings/use-messages)
- Switching languages with [``](/docs/react-native/api/components/locale-selector)
## Next steps
- Explore: [Variables Guide](/docs/react-native/guides/variables), [Branching Guide](/docs/react-native/guides/branches), [Strings Guide](/docs/react-native/guides/strings), [Changing Languages](/docs/react-native/guides/languages)
# react-native: Deploy to Production
URL: https://generaltranslation.com/en-US/docs/react-native/tutorials/quickdeploy.mdx
---
title: Deploy to Production
description: Let's deploy your React Native app with GT
---
{/* AUTO-GENERATED: Do not edit directly. Edit the template in content/docs-templates/ instead. */}
## Overview
This is a short tutorial to help you deploy your React Native app with GT.
In total, this should take less than 5 minutes to complete.
We will do this in 3 steps:
Add your production API keys.
Run the `gt configure` command to configure your project.
Add the translate command to your build script.
## Prerequisites
We'll assume that you have already set up your React Native app with GT.
If you haven't, first set up your project by following the [Quickstart Guide](/docs/react-native).
## Step 1: Add your production API keys 🔑
To deploy your app to production, you'll need to use a production API key.
From your [dashboard](https://generaltranslation.com/dashboard), go to **API Keys** in the sidebar.
Click on **Create API Key**, and add them to your production environment.
```bash copy
GT_API_KEY="YOUR_GT_API_KEY"
GT_PROJECT_ID="YOUR_GT_PROJECT_ID"
```
**Protect Your API Keys!**
Production keys should **only** ever be used in production.
Likewise, development keys should **only** ever be used in development.
*Never commit your API keys to a public repository!*
## Step 2: Run the `gt configure` command 🔧
If you've previously run the Setup Wizard, you can skip this step.
The setup wizard will have already run the `gt configure` command for you.
Run the `gt configure` command to configure your project.
```bash copy
npx gt configure
```
If you do not want your translations to be hosted on the GT CDN, select "No" when asked.
You will also need to configure the [`loadTranslations`](/docs/react-native/api/config/load-translations) function.
## Step 3: Add the translate command to your build script 🏗️
The last step is to add the [translate command](/docs/cli/translate) to your build script.
Make sure that the translate command comes before the build command.
```json title="package.json" copy
{
"scripts": {
"build": "npx gt translate && <...YOUR_BUILD_COMMAND...>"
}
}
```
That's it! Now, when you deploy your app to production and run `npm run build`,
your project will be automatically translated and deployed alongside your app.
---
## Next steps
* See the [CLI docs](/docs/cli) for more information on the CLI tool.
* Learn about the different configuration options for the CLI tool [here](/docs/cli/configure).
* Read about the difference between production and development environments [here](/docs/react-native/concepts/environments).
# react-native: React Native Quickstart with Expo
URL: https://generaltranslation.com/en-US/docs/react-native/tutorials/quickstart-expo.mdx
---
title: React Native Quickstart with Expo
description: Add multiple languages to your Expo app in under 10 minutes
---
By the end of this guide, your Expo app will display content in multiple languages, with a language switcher your users can interact with.
**Prerequisites:**
- An Expo project (SDK 49+)
- Node.js 18+
`gt-react-native` is still experimental and may not work for all projects.
Please let us know if you encounter any issues by [opening an issue on GitHub](https://github.com/generaltranslation/gt/issues).
**Want automatic setup?** Run `npx gt@latest` to configure everything with the [Setup Wizard](/docs/cli/init). This guide covers manual setup.
Looking for a bare React Native CLI project? See the [React Native Quickstart](/docs/react-native/tutorials/quickstart).
---
## Step 1: Install the packages
`gt-react-native` is the library that powers translations in your app. `gt` is the CLI tool that prepares translations for production.
```bash
npm i gt-react-native
npm i -D gt
```
```bash
yarn add gt-react-native
yarn add --dev gt
```
```bash
bun add gt-react-native
bun add --dev gt
```
```bash
pnpm add gt-react-native
pnpm add --save-dev gt
```
---
## Step 2: Create a translation config file
Create a **`gt.config.json`** file in your project root. This tells the library which languages you support:
```json title="gt.config.json"
{
"defaultLocale": "en",
"locales": ["es", "fr", "ja"],
"files": {
"gt": {
"output": "content/[locale].json"
}
}
}
```
- **`defaultLocale`** — the language your app is written in (your source language).
- **`locales`** — the languages you want to translate into. Pick any from the [supported locales list](/docs/platform/supported-locales).
- **`files.gt.output`** — where the CLI saves translation files. `[locale]` is replaced with each language code (e.g., `content/es.json`).
---
## Step 3: Set up polyfills
React Native's JavaScript runtime doesn't include the `Intl` APIs that `gt-react-native` needs. The easiest fix is the included Babel plugin.
Add it to your Babel config:
```js title="babel.config.js"
const gtPlugin = require('gt-react-native/plugin');
const gtConfig = require('./gt.config.json');
module.exports = function (api) {
api.cache(true);
return {
presets: ['babel-preset-expo'],
plugins: [
[
gtPlugin,
{
locales: [gtConfig.defaultLocale, ...gtConfig.locales],
entryPointFilePath: require.resolve('expo-router/entry'),
},
],
],
};
};
```
Install the FormatJS polyfills and import them at the top of your entry file. You need base polyfills plus locale-specific data for each language you support.
See [FormatJS's polyfill documentation](https://formatjs.github.io/docs/polyfills) for the full list. At minimum you need:
```tsx title="index.js"
import '@formatjs/intl-getcanonicallocales/polyfill';
import '@formatjs/intl-locale/polyfill';
import '@formatjs/intl-pluralrules/polyfill-force';
import '@formatjs/intl-numberformat/polyfill';
import '@formatjs/intl-datetimeformat/polyfill';
import '@formatjs/intl-datetimeformat/add-all-tz';
// Add locale data for each language:
import '@formatjs/intl-pluralrules/locale-data/en';
import '@formatjs/intl-pluralrules/locale-data/es';
import '@formatjs/intl-numberformat/locale-data/en';
import '@formatjs/intl-numberformat/locale-data/es';
// ... repeat for each locale and polyfill
```
---
## Step 4: Create a translation loader
Metro (Expo's bundler) doesn't support dynamic imports, so you need to explicitly map each locale to its translation file:
```ts title="loadTranslations.ts"
const translations: Record = {
es: require("@/content/es.json"),
fr: require("@/content/fr.json"),
ja: require("@/content/ja.json"),
};
export function loadTranslations(locale: string) {
return translations[locale] ?? {};
}
```
These files are generated by the CLI when you run `npx gt translate`.
---
## Step 5: Add the GTProvider to your layout
The **`GTProvider`** component gives your entire app access to translations. Add it to your root layout:
```tsx title="app/_layout.tsx"
import { Slot } from 'expo-router';
import { GTProvider } from 'gt-react-native';
import gtConfig from '../gt.config.json';
import { loadTranslations } from '../loadTranslations';
export default function RootLayout() {
return (
);
}
```
`GTProvider` manages locale state and makes translations available to all child components. The `devApiKey` prop enables on-demand translation during development.
---
## Step 6: Mark content for translation
Wrap any text you want translated with the **``** component:
```tsx title="app/index.tsx"
import { Text, View } from 'react-native';
import { T } from 'gt-react-native';
export default function Home() {
return (
Welcome to my app
This content will be translated automatically.
);
}
```
Everything inside `` gets translated as a unit.
---
## Step 7: Add a language switcher
Use the **`useLocaleSelector`** hook to build a language picker. Unlike `gt-react`, `gt-react-native` does not export a pre-built `` component — you build your own UI with the hook:
```tsx title="app/index.tsx"
import { Text, View, Pressable } from 'react-native';
import { T, useLocaleSelector } from 'gt-react-native';
export default function Home() {
const { locales, locale, setLocale } = useLocaleSelector();
return (
{locales.map((l) => (
setLocale(l)}>