diff --git a/devlog/en-US/gt-sanity_v3_1_0.mdx b/devlog/en-US/gt-sanity_v3_1_0.mdx index a22bdfd6f..7954c9d66 100644 --- a/devlog/en-US/gt-sanity_v3_1_0.mdx +++ b/devlog/en-US/gt-sanity_v3_1_0.mdx @@ -9,7 +9,7 @@ tags: ['gt-sanity', 'v3.1.0', 'sanity', 'cms', 'translation', 'minor'] Translated content rarely stays exactly as it arrives. Editors fix a term, tighten a headline, adjust tone for a market — and until now, the next translation run regenerated all of it. -`gt-sanity` v3.1 adds **Save local edits**: the translations Sanity already holds are uploaded to General Translation before a translation run, so content whose source text has not changed keeps its existing wording. It is off by default and opt-in per Studio session. +`gt-sanity` v3.1 adds **Save local edits**: the translations Sanity already holds are uploaded to General Translation before a translation run, so content whose source text has not changed keeps its existing wording. It is off by default. Since v3.1.4, the plugin remembers the editor's choice for each Sanity project and dataset. The release also adds a **Save Local Edits** action for uploading existing translations without starting a run, and a **Retranslate from scratch** option for deliberately regenerating everything. @@ -41,7 +41,7 @@ export default defineConfig({ }); ``` -`preserveExistingTranslations` seeds the toggle when the Studio loads. Editors can flip it for their session from the UI. +`preserveExistingTranslations` seeds the toggle when the Studio loads. Editors can change it from the UI; since v3.1.4, that choice is stored in the browser and takes precedence over the configured default on later visits. ### Sanity becomes the source of truth diff --git a/docs/en-US/cli/reference/commands/translate.mdx b/docs/en-US/cli/reference/commands/translate.mdx index 17308a070..341f9f94b 100644 --- a/docs/en-US/cli/reference/commands/translate.mdx +++ b/docs/en-US/cli/reference/commands/translate.mdx @@ -20,8 +20,8 @@ npx gt translate 1. Reads `gt.config.json` to determine the target locales, the files to translate, and their output paths. 2. For `gt-next`, `gt-react`, `gt-react-native`, and `gt-tanstack-start` projects, scans your `src` globs for inline content — [``](/docs/react/reference/components/t) components and [`useGT`](/docs/react/reference/hooks/use-gt) calls — and includes your dictionary file. 3. Auto-detects a third-party i18n library from `package.json` — `next-intl` or `i18next` (with `i18next-icu` support) — and translates its JSON files while respecting that library's syntax. -4. Detects local edits to previously downloaded translations and saves them to the platform. Pass `--no-save-local` to skip this step. -5. Stages the collected content and downloads the results in one step. Internally this is [`gt stage`](/docs/cli/reference/commands/stage) followed by [`gt download`](/docs/cli/reference/commands/download); use the split commands to run those parts separately. Because Lottie layout processing is asynchronous, a project with `.lottie` files exits here when `stageTranslations` is `false` and directs you to the split flow. +4. Stages the collected content with [`gt stage`](/docs/cli/reference/commands/stage): it uploads sources, detects and saves local edits to previous translations unless `--no-save-local` is set, then enqueues translation jobs. +5. Downloads the results with [`gt download`](/docs/cli/reference/commands/download). Use the split commands to run staging and download separately. Because Lottie layout processing is asynchronous, a project with `.lottie` files exits here when `stageTranslations` is `false` and directs you to the split flow. 6. Saves translations to your codebase, and to the CDN when `--publish` or the [`publish`](/docs/cli/reference/config#publish) config key is set. By default, the CLI syncs local translation edits before starting new work and does not overwrite them unless the source content has changed. Use `--force` to re-translate everything, or `--force-download` to re-download without re-translating. diff --git a/docs/en-US/integrations/sanity/guides/configuring-sanity.mdx b/docs/en-US/integrations/sanity/guides/configuring-sanity.mdx index 90c8f57d6..dda5a83e0 100644 --- a/docs/en-US/integrations/sanity/guides/configuring-sanity.mdx +++ b/docs/en-US/integrations/sanity/guides/configuring-sanity.mdx @@ -33,6 +33,48 @@ export default defineConfig({ }); ``` +## Browse translations by locale [#browse-locales] + +Sanity normally lists translated documents alongside their source. Use `gtStructureItems` to group each translatable document type into one pane per locale while keeping your other structure items. + +```ts title="sanity.config.ts" +import { defineConfig } from 'sanity'; +import { structureTool } from 'sanity/structure'; +import { gtPlugin, gtStructureItems } from 'gt-sanity'; + +export default defineConfig({ + plugins: [ + gtPlugin({ + sourceLocale: 'en', + locales: ['es', 'zh', 'ja'], + translateDocuments: [{ type: 'article' }, { type: 'page' }], + }), + structureTool({ + structure: (S, context) => + S.list() + .title('Content') + .items([ + ...gtStructureItems(S, context), + S.divider(), + ...S.documentTypeListItems(), + ]), + }), + ], +}); +``` + +The source-locale pane includes documents with no language field, so content created before the plugin still appears. Types localized in place with internationalized arrays are skipped because their translations stay in the source document. + +If the Studio needs only the locale-grouped types, pass the complete `gtStructure()` resolver to `structureTool`: + +```ts +import { gtStructure } from 'gt-sanity'; + +structureTool({ structure: gtStructure() }); +``` + +Pass `types` to either helper to override which document types are grouped. Use `sourceTitle` to rename the source pane, or `localeTitle` to build custom target-pane titles. See the [structure helper reference](/docs/integrations/sanity/reference/plugin-configuration#structure-helpers). + ## Set source and target locales [#set-locales] Use `sourceLocale` for the source language and `locales` for the target languages. diff --git a/docs/en-US/integrations/sanity/guides/managing-translations.mdx b/docs/en-US/integrations/sanity/guides/managing-translations.mdx index e63c2d5e3..aa474f2ab 100644 --- a/docs/en-US/integrations/sanity/guides/managing-translations.mdx +++ b/docs/en-US/integrations/sanity/guides/managing-translations.mdx @@ -26,7 +26,7 @@ The plugin registers a site-wide **Translations** tool that lists every translat - Patch references across translated documents (**Patch References**). - Publish translated documents whose source document is published (**Publish Translations**). -Turn on **Auto-refresh** to poll translation status, or use **Refresh** to check once. +Auto-refresh and auto-import are on by default. Auto-patch and auto-publish are off. Changes to these switches and **Save local edits** are remembered in browser storage for the current Sanity project and dataset. *Note: **Import Missing**, **Patch References**, and **Publish Translations** depend on document-level `translation.metadata`. For field-level localization, use **Import All** or import a locale from its status row, then review and publish the source document through Sanity's normal workflow.* @@ -43,12 +43,22 @@ Generated translations must be imported into Sanity. For document-level localiza Translated documents may reference other documents. Reference patching rewrites each reference `_ref` to point to the referenced document's translation for the same locale, when one exists. The plugin resolves these from the `translation.metadata` documents. -Use **Patch References** on the Translations tool to run this across existing translated documents. In the single-document dialog, it also runs automatically after import (auto-patch is on by default there). +Use **Patch References** on the Translations tool to run this across existing translated documents, or turn on **Auto-patch after import** in the single-document dialog. Auto-patch is off by default. + +If a translated document is already published and has no draft, patching creates a draft from the published document and updates that draft. It does not change the published document directly. ## Publish translations [#publish] Use **Publish Translations** to publish translated documents in bulk. The plugin publishes only translation documents whose source document is published. This is useful after importing many translations or patching references across a locale. +Imported document-level translations are created as drafts. Turn on **Auto-publish after import** to publish them automatically, or leave the default off to review them before publishing. + +## Inspect debug information [#debug-info] + +The footer of the **Translations** tool and document dialog shows the installed `gt-sanity` version. Click **Debug info** to inspect and copy the plugin's effective setup for a support request. + +The output includes resolved locales, translation mode, document and field rules, current preference values, translation counts, the Sanity project and dataset, and whether the secrets document was found. It never includes the API key, only whether one is configured. + ## Manage field behavior [#field-behavior] Use field matchers when some fields should not be translated normally. Each matcher targets fields with a JSONPath `property` expression and, optionally, a document `_id`. diff --git a/docs/en-US/integrations/sanity/guides/querying-translations.mdx b/docs/en-US/integrations/sanity/guides/querying-translations.mdx index 39803922a..d5eb03d8f 100644 --- a/docs/en-US/integrations/sanity/guides/querying-translations.mdx +++ b/docs/en-US/integrations/sanity/guides/querying-translations.mdx @@ -88,7 +88,7 @@ If your plugin config sets `languageField: 'locale'`, query `locale` instead of ### Query translated references -After references are patched, translated documents point to the translated versions of referenced documents. Query them as you normally would. +Reference patching updates the translated document's draft, creating one from the published state when needed. Publish the patched draft before querying from the published perspective. The translated document then points to translated versions of referenced documents. ```text *[_type == "article" && language == "es"]{ diff --git a/docs/en-US/integrations/sanity/guides/translating-content.mdx b/docs/en-US/integrations/sanity/guides/translating-content.mdx index 47c6c6a97..4dde288b1 100644 --- a/docs/en-US/integrations/sanity/guides/translating-content.mdx +++ b/docs/en-US/integrations/sanity/guides/translating-content.mdx @@ -23,7 +23,9 @@ The **Translate** action is available on every document, but the translation too 3. Under **Translate**, select the target locales. 4. Click **Translate**. -Once translations are generated, the dialog polls for progress under **Translation Status**. For document-level localization, the plugin imports each locale document, patches its references, and publishes it because auto-import, auto-patch, and auto-publish are enabled by default. You can toggle each behavior, import a locale manually from its status row, or use **Import All**, **Patch References**, and **Publish Translations**. +The dialog shows each locale as **Not translated**, **Translating…**, **Ready to import**, or **Imported** under **Translation Status**. While a run is outstanding, the **Translate** button stays disabled. + +For document-level localization, auto-refresh and auto-import are on by default, so translations that finish while the dialog is open are imported as drafts. Auto-patch and auto-publish are off by default. You can toggle each behavior, import a locale manually from its status row, or use **Import All**, **Patch References**, and **Publish Translations**. A translation that was already complete when you opened the dialog is not re-imported automatically, which preserves edits to its Sanity document. For field-level localization, import merges the translated values into `internationalizedArray*` fields on the same document. Review and publish that document in Sanity. Reference patching and the translation publishing controls apply only to document-level translations. @@ -54,7 +56,7 @@ Turn on **Save local edits** to keep them. With the toggle on, each translation The toggle is in the **Translations** tool, and on the document tab as **Save local edits before translating**. It is off by default. Turning it on asks for confirmation first; turning it off takes effect immediately. -The toggle applies to translation runs started from the current Studio session and resets when the Studio reloads. Set the state it starts from with [`preserveExistingTranslations`](/docs/integrations/sanity/reference/plugin-configuration#preserve-existing-translations). +The plugin remembers this choice in browser storage for the current Sanity project and dataset. It takes precedence over the configured [`preserveExistingTranslations`](/docs/integrations/sanity/reference/plugin-configuration#preserve-existing-translations) default on later visits. Both localization strategies are covered. Document-level translations are read through `translation.metadata`, preferring drafts over published documents so unpublished edits count. Field-level translations are read from the source document's internationalized arrays. Locales with no existing content are skipped. @@ -97,7 +99,7 @@ Slug fields are *not* stopped by default, so a slug's `current` value is sent fo Document-level translations can reference other documents. The plugin looks up each referenced document's translation and rewrites the reference to point to the correct locale version, when one exists. -This runs automatically after import in the document dialog, and on demand with **Patch References** on the Translations page. See [Manage translations](/docs/integrations/sanity/guides/managing-translations#patch-references). +Turn on **Auto-patch after import** to run this after each import, or use **Patch References** on demand. Auto-patch is off by default. See [Manage translations](/docs/integrations/sanity/guides/managing-translations#patch-references). ## Handle slugs and copied fields [#slugs-fields] diff --git a/docs/en-US/integrations/sanity/quickstart.mdx b/docs/en-US/integrations/sanity/quickstart.mdx index 5815a4180..e016c6ea8 100644 --- a/docs/en-US/integrations/sanity/quickstart.mdx +++ b/docs/en-US/integrations/sanity/quickstart.mdx @@ -146,7 +146,9 @@ If you use multiple datasets, repeat this for each dataset. After verifying, del 3. Select target locales. 4. Click **Translate**. -With this document-level setup, the plugin polls for completed translations and imports them automatically. After import, it patches document references and publishes the translated documents because auto-import, auto-patch, and auto-publish are on by default in this dialog. +With this document-level setup, the plugin polls for completed translations and imports them automatically as drafts. Reference patching and publishing are off by default; use the dialog controls or configure their initial state with [`autoPatchReferences`](/docs/integrations/sanity/reference/plugin-configuration#auto-patch-references) and [`autoPublish`](/docs/integrations/sanity/reference/plugin-configuration#auto-publish). + +Review the imported documents in Sanity's **Drafts** perspective, then publish them before querying from a published-only frontend. See the full guides to [translate content](/docs/integrations/sanity/guides/translating-content) and [manage translations](/docs/integrations/sanity/guides/managing-translations). diff --git a/docs/en-US/integrations/sanity/reference/plugin-configuration.mdx b/docs/en-US/integrations/sanity/reference/plugin-configuration.mdx index c58f82e84..7733966e0 100644 --- a/docs/en-US/integrations/sanity/reference/plugin-configuration.mdx +++ b/docs/en-US/integrations/sanity/reference/plugin-configuration.mdx @@ -37,6 +37,10 @@ gtPlugin({ | [`fieldLevelLocalization`](#field-level-localization) | Alias for `internationalizedArray`. | `GTFieldLevelLocalizationConfig` | Yes | — | | [`translationLevel`](#translation-level) | Choose document-level, field-level, or mixed translation. | `'document' \| 'internationalizedArray' \| 'mixed'` | Yes | `'document'` | | [`fieldLevelDocuments`](#field-level-documents) | Document types that use field-level localization in mixed mode. | `TranslateDocumentFilter[] \| string[]` | Yes | `[]` | +| [`autoRefresh`](#auto-refresh) | Initial state of automatic translation-status polling. | `boolean` | Yes | `true` | +| [`autoImport`](#auto-import) | Initial state of automatic import when a translation completes. | `boolean` | Yes | `true` | +| [`autoPatchReferences`](#auto-patch-references) | Initial state of reference patching after import. | `boolean` | Yes | `false` | +| [`autoPublish`](#auto-publish) | Initial state of publishing after import. | `boolean` | Yes | `false` | | [`preserveExistingTranslations`](#preserve-existing-translations) | Initial state of the **Save local edits** toggle. | `boolean` | Yes | `false` | | [`ignoreFields`](#ignore-fields) | Fields copied from the source without translating. | `FieldMatcher[]` | Yes | `[]` | | [`dedupeFields`](#dedupe-fields) | Fields copied from the source and made unique per locale. | `FieldMatcher[]` | Yes | `[]` | @@ -273,6 +277,32 @@ defineField({ ## Translation workflow options [#workflow-options] +These options set the switches' initial values. When an editor changes a switch in the Studio, the plugin saves all five preferences to `localStorage`, keyed by Sanity project and dataset. Stored values take precedence over plugin configuration on later visits. If browser storage is unavailable, a change applies until the Studio reloads. + +### `autoRefresh` [#auto-refresh] + +**Type** `boolean` · **Optional** · **Default** `true` + +Sets the initial state of **Auto-refresh**. When enabled, the document dialog polls for translation status every 10 seconds. A manual **Refresh** checks once regardless of this setting. + +### `autoImport` [#auto-import] + +**Type** `boolean` · **Optional** · **Default** `true` + +Sets the initial state of **Auto-import when complete**. When enabled, the document dialog imports translations that complete while it is open. It does not automatically re-import translations that were already complete when the dialog opened, which prevents existing Sanity edits from being overwritten. Starting a new translation run resets that baseline. + +### `autoPatchReferences` [#auto-patch-references] + +**Type** `boolean` · **Optional** · **Default** `false` + +Sets the initial state of **Auto-patch after import** for document-level translations. When enabled, an imported document's references are repointed to translated documents for the same locale. If the translated document is already published and has no draft, the plugin creates a draft from the published state and patches the draft instead of changing published content. + +### `autoPublish` [#auto-publish] + +**Type** `boolean` · **Optional** · **Default** `false` + +Sets the initial state of **Auto-publish after import** for document-level translations. Imports always create or update drafts. Enable this option to publish each imported translation automatically when its source document is published. + ### `preserveExistingTranslations` [#preserve-existing-translations] **Type** `boolean` · **Optional** · **Default** `false` @@ -288,7 +318,7 @@ gtPlugin({ }); ``` -This option seeds the toggle when the Studio loads. Editors can turn it on or off for their session from the **Translations** tool or the document tab, and that choice takes precedence for the rest of the session. +Editors can change this preference from the **Translations** tool or document dialog. Like the other workflow preferences, their stored choice takes precedence over the configured initial value on later visits. With the toggle on, what is in Sanity replaces whatever General Translation holds for that version of the document, including a translation that has finished but has not been imported yet. Import any pending translations before enabling it. @@ -296,6 +326,45 @@ This option seeds the toggle when the Studio loads. Editors can turn it on or of See [Keep edits to translations](/docs/integrations/sanity/guides/translating-content#preserve-edits). +### Version history + +| Version | Changes | +| --- | --- | +| `3.1.4` | Added all five plugin options and per-project, per-dataset persistence. Changed the `autoPatchReferences` and `autoPublish` defaults to `false`; `autoRefresh` and `autoImport` remain `true`. | + +## Studio structure helpers [#structure-helpers] + +`gt-sanity` exports two opt-in helpers for grouping document-level translations by locale in Sanity's structure tool. + +| Helper | Description | Returns | +| --- | --- | --- | +| `gtStructureItems` | Build locale-grouped list items to compose into a custom structure. | `ListItemBuilder[]` | +| `gtStructure` | Build a complete **Content** structure containing the locale-grouped items. | `StructureResolver` | + +```ts +type GTStructureOptions = { + types?: string[]; + sourceTitle?: string; + localeTitle?: (typeTitle: string, locale: string, label: string) => string; +}; + +function gtStructureItems( + S: StructureBuilder, + context?: StructureResolverContext, + options?: GTStructureOptions +): ListItemBuilder[]; + +function gtStructure(options?: GTStructureOptions): StructureResolver; +``` + +By default, the helpers group the document types in `translateDocuments`. Types localized in place through internationalized arrays are excluded. The source pane includes documents whose language field is missing or matches `sourceLocale`; each target pane includes documents whose language field matches that locale. + +- `types` overrides the document types selected from plugin configuration. +- `sourceTitle` replaces the source pane's locale label. +- `localeTitle` receives the schema type title, locale code, and formatted locale label, then returns each target pane title. + +When no document types can be resolved, the helper logs a warning and returns no list items. See [Browse translations by locale](/docs/integrations/sanity/guides/configuring-sanity#browse-locales) for configuration examples. + ## Field matchers [#field-matchers] `ignoreFields`, `dedupeFields`, and `skipFields` each take an array of `FieldMatcher` objects. A matcher targets fields by a JSONPath `property` expression and, optionally, restricts to one source document by `documentId`. To exclude a field everywhere it appears, prefer marking it in the schema with the [schema exclusion options](#schema-exclusion). @@ -489,9 +558,10 @@ Slug fields are *not* stopped by default, so a slug's `current` string is transl ## Exported helpers [#helpers] -`gt-sanity` also exports building blocks for advanced serialization and custom document nodes. Most projects do not need them. +`gt-sanity` also exports building blocks for Studio structure, advanced serialization, and custom document nodes. Most projects do not need them. - `TranslationsTab` — the document tab component for `structureTool`. See [Configure Sanity](/docs/integrations/sanity/guides/configuring-sanity#translations-tab). +- `gtStructure` / `gtStructureItems` and `GTStructureOptions` — locale-grouped Studio structure helpers. See [Studio structure helpers](#structure-helpers). - `attachGTData` / `detachGTData` — attach and read the encoded mark data used by custom serializers. - `BaseDocumentSerializer`, `BaseDocumentDeserializer`, `BaseDocumentMerger` — the default serialize, deserialize, and merge implementations. - `defaultStopTypes`, `customSerializers` — the default stop types and serializer set. diff --git a/docs/en-US/platform/core/guides/locale-codes.mdx b/docs/en-US/platform/core/guides/locale-codes.mdx index 0d2425234..f2fc9b63b 100644 --- a/docs/en-US/platform/core/guides/locale-codes.mdx +++ b/docs/en-US/platform/core/guides/locale-codes.mdx @@ -50,10 +50,12 @@ Some locale tags are functionally equivalent for translation. For example, `fr` means French, which is equivalent to: - `fr-FR`, which means French as used in France. -- `fr-FR-Latn` which means French as used in France, written with the Latin alphabet. +- `fr-Latn-FR`, which means French as used in France, written with the Latin alphabet. The General Translation libraries and platform usually do not distinguish between equivalent codes, since the translation output would be the same. +The Files API resolves request locales to the supported locale used for storage. Batch [download](/docs/platform/openapi/reference/files/download-many) and [file information](/docs/platform/openapi/reference/files/file-info) responses preserve the locale code from each request, even when two codes resolve to the same stored translation. + ### Common locale codes diff --git a/docs/en-US/platform/core/reference/gt-class-methods/project/project-management.mdx b/docs/en-US/platform/core/reference/gt-class-methods/project/project-management.mdx index f035df8a1..c0ea744cb 100644 --- a/docs/en-US/platform/core/reference/gt-class-methods/project/project-management.mdx +++ b/docs/en-US/platform/core/reference/gt-class-methods/project/project-management.mdx @@ -158,4 +158,4 @@ submitUserEditDiffs(payload: { }): Promise ``` -Each `SubmitUserEditDiff` includes `fileName`, `locale`, `diff`, `branchId`, `versionId`, `fileId`, and `localContent`. Locales are normalized to canonical form before submission, and diffs are batched automatically. Resolves when submission succeeds. +Each `SubmitUserEditDiff` includes `fileName`, `locale`, `diff`, `branchId`, `versionId`, `fileId`, and `localContent`. The instance resolves custom locale aliases before submission, then the API resolves each locale to the supported locale used for storage. Equivalent codes such as `ja` and `ja-JP` update the same stored translation. Diffs are batched automatically. Resolves when submission succeeds. diff --git a/docs/en-US/platform/core/reference/gt-class-methods/translation/download-file-batch.mdx b/docs/en-US/platform/core/reference/gt-class-methods/translation/download-file-batch.mdx index 2761d6945..65a9ba9bc 100644 --- a/docs/en-US/platform/core/reference/gt-class-methods/translation/download-file-batch.mdx +++ b/docs/en-US/platform/core/reference/gt-class-methods/translation/download-file-batch.mdx @@ -34,7 +34,8 @@ downloadFileBatch( ## How it works [#how-it-works] -- **Order.** Files are returned in the same order as the requested items when possible. +- **Order.** Do not depend on response order. Match each result by its `fileId`, `branchId`, `versionId`, and `locale`. +- **Locale resolution.** Each requested locale is resolved to the supported locale used for storage. Equivalent codes can resolve to one stored translation; if you request both `ja` and `ja-JP`, each request produces a result labeled with the locale you passed. - **Partial success.** A failed individual download within the batch does not cause the whole batch to fail. - **Readiness.** Use [`queryFileData`](/docs/platform/core/reference/gt-class-methods/translation/query-file-data) to verify files are ready before downloading. - **Binary formats.** Text formats return decoded UTF-8 data. `LOTTIE` remains base64-encoded so callers can reconstruct the binary `.lottie` file without corrupting its bytes. @@ -169,5 +170,5 @@ downloadResult.files.forEach((file) => { - Text files are returned as UTF-8 strings. Decode `LOTTIE` data from base64 to write the binary `.lottie` file. - Use [`queryFileData`](/docs/platform/core/reference/gt-class-methods/translation/query-file-data) to verify files are ready for download first. -- Files are returned in the same order as the requested items when possible. +- Do not depend on response order; match results by file, version, branch, and locale identifiers. - Failed individual file downloads within the batch do not cause the entire batch to fail. diff --git a/docs/en-US/platform/core/reference/gt-class-methods/translation/download-file.mdx b/docs/en-US/platform/core/reference/gt-class-methods/translation/download-file.mdx index b42fab75d..2bef455b7 100644 --- a/docs/en-US/platform/core/reference/gt-class-methods/translation/download-file.mdx +++ b/docs/en-US/platform/core/reference/gt-class-methods/translation/download-file.mdx @@ -48,7 +48,8 @@ downloadFile( ## How it works [#how-it-works] -- **Source vs. translation.** When a `locale` is provided, the file must have a completed translation for that locale. When no `locale` is provided, the source file is returned. +- **Source vs. translation.** When a `locale` is provided, the file must have a completed translation for the resolved supported locale. When no `locale` is provided, the source file is returned. +- **Locale resolution.** The requested locale is resolved to the supported locale used for storage. For example, `ja-JP` resolves to `ja`; distinct supported locales such as `en-GB` remain unchanged. - **Format preserved.** The returned string is in the same format as the original source file; for translations, all translatable text is converted to the target locale. - **Failure.** The call fails if the file is not found. @@ -134,6 +135,6 @@ console.log('Spanish translation:', spanishContent); ## Notes [#notes] - Retrieves the downloaded file as a UTF-8 string. -- When a locale is provided, the file must have a completed translation for that locale. +- When a locale is provided, the file must have a completed translation for its resolved supported locale. - When no locale is provided, the source file is returned. - The call fails if the file is not found. diff --git a/docs/en-US/platform/core/reference/gt-class-methods/translation/query-file-data.mdx b/docs/en-US/platform/core/reference/gt-class-methods/translation/query-file-data.mdx index bd7cba0f3..59ce64e76 100644 --- a/docs/en-US/platform/core/reference/gt-class-methods/translation/query-file-data.mdx +++ b/docs/en-US/platform/core/reference/gt-class-methods/translation/query-file-data.mdx @@ -38,6 +38,7 @@ queryFileData( - **Completion.** A translation is complete when its `completedAt` is not `null`. - **Lifecycle.** A completed translation may still require approval (`approvedAt`) before it is published (`publishedAt`). - **Batch monitoring.** Query many files at once for efficient status checking across multiple translation jobs. +- **Locale resolution.** Translation query locales are resolved to the supported locale used for storage. The response preserves the locale from each request, so equivalent codes requested separately, such as `ja` and `ja-JP`, each receive a result when they match the same stored translation. - **Versioning.** All file queries require `branchId` for versioning with branch support. ## Parameters [#parameters] diff --git a/docs/en-US/platform/locadex/reference/automations.mdx b/docs/en-US/platform/locadex/reference/automations.mdx index 139003638..ef96037ce 100644 --- a/docs/en-US/platform/locadex/reference/automations.mdx +++ b/docs/en-US/platform/locadex/reference/automations.mdx @@ -57,3 +57,5 @@ Click **Run now** on an automation detail page to confirm its repository, target An automation cannot produce correct results until its target directory is set up. If setup has not completed, the detail page shows **Run setup**. Choose the source locale and target languages, then start setup. Locadex prepares the repository and opens a pull request. Merge that pull request before running the automation. + +For supported React frameworks, setup follows the current server-rendered integration guide. It configures `gt.config.json`, runtime initialization, translation loading, and [`GTProvider`](/docs/react/reference/components/gt-provider) placement, then runs the repository's existing build or type-check command. Setup does not wrap application strings with [``](/docs/react/reference/components/t) or other translation APIs; the **Generate code** automation handles source content after the setup pull request is merged. diff --git a/docs/en-US/platform/openapi/reference/files/download-many.mdx b/docs/en-US/platform/openapi/reference/files/download-many.mdx index a7db5526f..b8613d92c 100644 --- a/docs/en-US/platform/openapi/reference/files/download-many.mdx +++ b/docs/en-US/platform/openapi/reference/files/download-many.mdx @@ -22,6 +22,8 @@ Fetch many files at once. To download a single file, use [Download file](/docs/p - Send 1 to 100 file references. Each is resolved independently and the successful results are returned together. - An entry without `locale` returns the source file; an entry with `locale` returns that translation. +- Requested locales are resolved to the supported locale used for storage. Equivalent codes can resolve to one stored translation; if you request both `ja` and `ja-JP`, each request produces a result labeled with the locale you passed. +- Do not depend on response order. Match each result by its file, branch, version, and locale identifiers. - A missing `branchId` resolves to the default branch. A missing `versionId` uses the branch head version, unless `useLatestAvailableVersion` is set. - File content is returned base64-encoded in the `data` field. `fileName` is present only on source files, and `locale` is present only on translated files. - For `LOTTIE`, `data` is the base64-encoded, reassembled `.lottie` file. Decode it to bytes rather than UTF-8 text. diff --git a/docs/en-US/platform/openapi/reference/files/download.mdx b/docs/en-US/platform/openapi/reference/files/download.mdx index 8ea183df5..f610013ae 100644 --- a/docs/en-US/platform/openapi/reference/files/download.mdx +++ b/docs/en-US/platform/openapi/reference/files/download.mdx @@ -23,6 +23,7 @@ Fetch one file. To download many files in one call, use [Download files](/docs/p ## How it works [#how-it-works] - Without a `locale` query parameter, the source file is returned. With `locale`, the matching translation is returned. +- The requested locale is resolved to the supported locale used for storage. For example, `ja-JP` resolves to `ja`; distinct supported locales such as `en-GB` remain unchanged. - A missing `branchId` resolves to the default branch. A missing `versionId` uses the branch head version. - The file content is returned base64-encoded in the `data` field. A missing file returns `404`. - For `LOTTIE`, `data` is the base64-encoded, reassembled `.lottie` file. Decode it to bytes rather than UTF-8 text. diff --git a/docs/en-US/platform/openapi/reference/files/file-info.mdx b/docs/en-US/platform/openapi/reference/files/file-info.mdx index 0ccea93d9..7afcc5247 100644 --- a/docs/en-US/platform/openapi/reference/files/file-info.mdx +++ b/docs/en-US/platform/openapi/reference/files/file-info.mdx @@ -22,6 +22,7 @@ Look up file metadata without downloading content. For per-locale translation pr - Provide `sourceFiles`, `translatedFiles`, or both. Each list is resolved independently and returned in its own array. - Only files that exist are returned; unmatched references are omitted rather than causing an error. +- Each translated-file locale is resolved to the supported locale used for storage. The response preserves the locale from each request, so equivalent codes requested separately, such as `ja` and `ja-JP`, each receive an entry when they match the same stored translation. - The response contains metadata only (locales, formats, timestamps), not file content. ## Request [#request] diff --git a/docs/en-US/platform/openapi/reference/files/submit-diffs.mdx b/docs/en-US/platform/openapi/reference/files/submit-diffs.mdx index 6fce3dc9c..044f681d4 100644 --- a/docs/en-US/platform/openapi/reference/files/submit-diffs.mdx +++ b/docs/en-US/platform/openapi/reference/files/submit-diffs.mdx @@ -20,7 +20,7 @@ Push local translation edits back to a Project. To replace whole files instead, ## How it works [#how-it-works] -- Entries are grouped by `branchId`, `fileId`, `versionId`, and `locale`. Only the first entry per group is applied, so duplicate groups in one request are deduplicated. +- Entries are grouped by `branchId`, `fileId`, `versionId`, and the resolved supported locale. Equivalent codes such as `ja` and `ja-JP` map to one storage locale and one group. Only the first entry per group is applied. - Entries with empty `localContent` are skipped. - For each remaining group, the stored translation is overwritten with `localContent`. A missing `branchId` resolves to the default branch. - The response reports how many translations were processed and how many entries were received. diff --git a/docs/en-US/react/(frameworks)/tanstack-start/index.mdx b/docs/en-US/react/(frameworks)/tanstack-start/index.mdx index 72b2dc536..b2bfe9c0c 100644 --- a/docs/en-US/react/(frameworks)/tanstack-start/index.mdx +++ b/docs/en-US/react/(frameworks)/tanstack-start/index.mdx @@ -13,6 +13,8 @@ If you are just getting started, follow the [TanStack Start Quickstart](/docs/re **Warning:** `gt-tanstack-start` is experimental and may have breaking changes. It is not yet recommended for production use. +*Note: The current setup requires `gt-tanstack-start` 11.1.5 or later.* + ## What is TanStack Start-specific [#overview] - **Request middleware.** Register [`gtMiddleware`](/docs/react/tanstack-start/reference/functions/gt-middleware) from `gt-tanstack-start` to create request-local state for server functions. diff --git a/docs/en-US/react/(frameworks)/tanstack-start/reference/functions/gt-middleware.mdx b/docs/en-US/react/(frameworks)/tanstack-start/reference/functions/gt-middleware.mdx index 9563de2de..4773aeb98 100644 --- a/docs/en-US/react/(frameworks)/tanstack-start/reference/functions/gt-middleware.mdx +++ b/docs/en-US/react/(frameworks)/tanstack-start/reference/functions/gt-middleware.mdx @@ -1,7 +1,7 @@ --- title: gtMiddleware -description: Create request-scoped locale state for General Translation server APIs in TanStack Start. API reference for gtMiddleware. +description: Create request-scoped locale state for TanStack Start server functions. API reference for gtMiddleware. --- diff --git a/docs/en-US/react/(frameworks)/tanstack-start/setup.mdx b/docs/en-US/react/(frameworks)/tanstack-start/setup.mdx index 28af40482..132bd8fb0 100644 --- a/docs/en-US/react/(frameworks)/tanstack-start/setup.mdx +++ b/docs/en-US/react/(frameworks)/tanstack-start/setup.mdx @@ -15,6 +15,8 @@ This page covers the TanStack Start-specific setup. For the full path including *Note: `gt-tanstack-start` is ESM-only. Use `import` syntax rather than CommonJS `require()`.* +*Note: This setup requires `gt-tanstack-start` 11.1.5 or later so [`gtMiddleware`](/docs/react/tanstack-start/reference/functions/gt-middleware) resolves from the package's main entry in client builds.* + ## Load translations [#load-translations] Create a [`loadTranslations`](/docs/react/reference/functions/load-translations) function that imports a locale's translation file. Keep the files under `src/` so Vite can import them. diff --git a/docs/en-US/react/react-spa-quickstart.mdx b/docs/en-US/react/react-spa-quickstart.mdx index 240c68536..8ff8adc2b 100644 --- a/docs/en-US/react/react-spa-quickstart.mdx +++ b/docs/en-US/react/react-spa-quickstart.mdx @@ -108,6 +108,10 @@ export default async function loadTranslations(locale: string) { This function loads JSON translation files from your `src/_gt/` directory. The CLI generates these files when you run [`npx gt translate`](/docs/cli/reference/commands/translate). + + **Rollup:** Plain Rollup cannot analyze the fully dynamic import above. Use the [static locale-loader map](/docs/react/guides/developing-spa-translations#setup) instead. + + ### 4. Initialize the library diff --git a/docs/en-US/react/reference/functions/get-translations-snapshot.mdx b/docs/en-US/react/reference/functions/get-translations-snapshot.mdx index 2deac7c3a..4a3585621 100644 --- a/docs/en-US/react/reference/functions/get-translations-snapshot.mdx +++ b/docs/en-US/react/reference/functions/get-translations-snapshot.mdx @@ -1,7 +1,7 @@ --- title: getTranslationsSnapshot -description: Load a locale's translations for GTProvider. API reference for getTranslationsSnapshot. +description: Load a locale's translations for . API reference for getTranslationsSnapshot. --- diff --git a/docs/en-US/react/tanstack-start-quickstart.mdx b/docs/en-US/react/tanstack-start-quickstart.mdx index 2009e9676..3165db1f7 100644 --- a/docs/en-US/react/tanstack-start-quickstart.mdx +++ b/docs/en-US/react/tanstack-start-quickstart.mdx @@ -55,6 +55,8 @@ Install `gt-tanstack-start` and `gt-react` as dependencies, and the [`gt` CLI](/ `gt-tanstack-start` is ESM-only. Use `import` syntax rather than CommonJS `require()`. +*Note: This setup requires `gt-tanstack-start` 11.1.5 or later so [`gtMiddleware`](/docs/react/tanstack-start/reference/functions/gt-middleware) resolves from the package's main entry in client builds.* + ### 2. Create `gt.config.json` Create a `gt.config.json` file in your project root. It declares your source language, your target locales, and where translation files are written.