# gt: General Translation CLI tool: .xcstrings
URL: https://generaltranslation.com/en-GB/docs/cli/reference/formats/xcstrings-files.mdx
Docs index: https://generaltranslation.com/llms.txt
Description: Translate Apple String Catalogs with the General Translation CLI. API reference for the .xcstrings file format.

The CLI translates `.xcstrings` files, which store source content and every locale in one String Catalogue. Support requires `gt` 2.21.0 or later.

## Overview [#overview]

| Topic                         | Description                                                               |
| ----------------------------- | ------------------------------------------------------------------------- |
| [Configuration](#config)      | Select catalogues and keep every locale in the same file.                 |
| [How it works](#how-it-works) | Slice source content for upload and merge translated locales on download. |
| [Local edits](#local-edits)   | Sync edits without treating other catalogue locales as changes.           |
| [Errors](#errors)             | Identify invalid catalogues and unsupported path settings.                |

## Configuration [#config]

Add an `xcstrings` entry under `files` with an `include` array that points directly to each catalogue.

```json title="gt.config.json"
{
  "defaultLocale": "en",
  "locales": ["es", "ja"],
  "files": {
    "xcstrings": {
      "include": ["Resources/Localizable.xcstrings"]
    }
  }
}
```

A String Catalogue holds every locale in one file and is updated in place. Its `include` patterns must not contain `[locale]`, and the `xcstrings` config does not accept `transform`.

The catalogue&#39;s `sourceLanguage` must resolve to the same canonical locale as `defaultLocale`. For example, a catalogue with `"sourceLanguage": "en"` can use `"defaultLocale": "en"`, but cannot use `"defaultLocale": "fr"`.

## How it works [#how-it-works]

On upload, the CLI reads the catalogue and sends a source-only slice to the API. Each entry keeps its source-language localisation when one exists; entries that use the key itself as source text stay in the slice without a `localizations` field. Existing target locales are not uploaded as source content.

On download, the CLI merges each target locale back into the catalogue on disk. It changes only that locale&#39;s localisation for matching entries. Other locales, comments, extraction states, substitutions, variations, and unrecognised fields remain in place.

If the downloaded translation contains a key that no longer exists in the local catalogue, the CLI skips that key and prints a warning. The downloaded file is serialised as two-space-indented JSON with a trailing newline.

## Local edits [#local-edits]

Download bookkeeping is stored per locale even though every locale shares one file. This prevents an unchanged target locale from being submitted as a local edit after another locale is merged into the catalogue.

Use [`gt save-local`](/docs/cli/reference/commands/save-local), [`gt translate --save-local`](/docs/cli/reference/commands/translate), or [`options.saveLocal: true`](/docs/cli/reference/config#save-local) to submit edited target localisations. Local-edit syncing is opt-in.

The Dashboard also opens `.xcstrings` translations in the editable Raw view. A saved edit updates only the selected target locale in the catalogue.

## Errors [#errors]

* Invalid JSON, a missing or empty `sourceLanguage`, or a non-object `strings` field causes the CLI to skip the catalogue and report the validation problem.
* A `sourceLanguage` that does not match `defaultLocale` stops the run before files are uploaded.
* An `include` pattern containing `[locale]` or an `xcstrings.transform` setting stops the run because translated locales must merge into the original catalogue.
* The reserved key `__proto__` is rejected in string and localisation maps. Keys named `constructor` or `prototype` are supported.

## Sitemap

See the full [sitemap](https://generaltranslation.com/sitemap.md) for all pages.
