> ## Documentation Index
> Fetch the complete documentation index at: https://developer.dittowords.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> These are Ditto's developer docs. Ditto is a single source of truth for product copy across design, review, localization, and code.
> The first step on any codebase is a scan: https://developer.dittowords.com/get-started/scan-your-repo.md. That page also covers reviewing the style guide Ditto drafts from the scan. After it, the follow-on guides are Connect Figma files and Set up localization (under /guides/) and Connect the Ditto MCP (the Setup page of the MCP reference).
> Two different MCP servers: the Ditto MCP server at https://api.dittowords.com/v2/mcp gives an agent a workspace's text and style guide rules; the documentation MCP server at https://developer.dittowords.com/mcp searches these docs.
> Prefer logging in with a Ditto account (npx -y @dittowords/cli@latest login; OAuth in MCP clients) over API keys. API keys are for CI and headless clients only.
> Commands are complete as written and use npx -y @dittowords/cli@latest; nothing needs a global install.

# Set up localization

> Manage and automate localization in Ditto: add locales as variants, translate with AI, preview in design, and bring localized string files to code.

Manage and automate localization at any scale: automatically translate text, preview it in design, and bring it to code. Ditto keeps every language of a string on the same text item, so one developer ID resolves to the right text for each locale.

## How localization works in Ditto

* A **locale** is a variant with a locale code (`de-DE`, `fr`, `es-419`); every text item and library component carries base text plus its variants. Definitions: [Variants and locales](/concepts#variants-and-locales).
* The **base locale** is the language of your base text. Set it in a project's or the library's **Variant & locale settings** if your source copy is not English.
* Locale-scoped [style guides](/concepts#style-guides-and-rules) apply when text is written or translated for that locale; variables and plurals carry into every variant.

If your codebase already had translation files when you [scanned](/get-started/scan-your-repo) it, Ditto found the locales, proposed one variant per locale during review, and imported each locale's text as variant text. Check **Variants** in the left sidebar to see them.

## Step 1: add the locales you need

Pick one:

* **In the Ditto app**: open **Variants** in the left sidebar, click **+ New variant**, enter a name, choose the locale, and click **Create Variant**.
* **From your agent**: "Create variants for German (de-DE) and Brazilian Portuguese (pt-BR)." The agent calls `create_variants` with a `localeCode` for each. Read the developer IDs off the response; they are generated from the name unless you pass one.
* **From the API**: `POST /v2/variants` with `name` and `localeCode`. See [Create variants](/api-reference/variants/create-variants).

Add the variant to the text that needs it: in a project, open the **…** menu, choose **Variant configuration**, and add the variant to all project text (optionally with auto-translate on). For a single text item, open its variant tab and click **Add variant**.

## Step 2: get the translations

Choose the workflow that fits your team; they can be combined.

<Tabs>
  <Tab title="Magic Translate (in Ditto)">
    Ditto's AI translation uses the variant's locale code as the target and applies any style guide scoped to that locale.

    * **One text item**: select it, open its variant tab, click **Add variant**, choose the locale variant, and click **Translate** under the text.
    * **A whole project**: open the project's **…** menu, choose **Variant configuration**, add the locale variants, turn on auto-translate for the ones you want translated automatically, and click **Save**.
    * **The component library**: the same **Variant configuration** flow from the library.

    Translations can be reviewed, edited, and scored in Ditto before developers pull them.
  </Tab>

  <Tab title="Crowdin or Lokalise">
    Ditto connects to **Crowdin** and **Lokalise**. Open **Settings › Connections** in Ditto, choose the platform, and follow the connection steps. Translated text returns to the variants on your text items, so the developer handoff below is unchanged.
  </Tab>

  <Tab title="Your own translators or pipeline">
    Write variant text with the API or the MCP:

    * API: `PATCH /v2/textItems` or `PATCH /v2/components` with `variantId` (a variant developer ID) in the payload updates that variant's text instead of the base. See [Update text items](/api-reference/text-items/patch-text-items).
    * MCP: `update_text_items` or `update_library_components` with the variant developer ID from `list_variants`.

    Export the base text for translators with `GET /v2/textItems/export` in any format below, translate it, and write it back the same way.
  </Tab>
</Tabs>

## Step 3: pull localized files into your app

The CLI writes one file per variant per source into `./ditto` by default: `{project_id}___{variant_id}.{ext}` for each project and `components__{variant_id}.{ext}` for the component library, where `variant_id` is the variant's developer ID or `base`. Configure what to pull in `ditto/config.yml` at the repo root and run:

```bash theme={null}
npx -y @dittowords/cli@latest pull
```

### Choose a format

| Your platform         | `outputs` entry                                     | Files you get                                                                                                      | Format details                                                                                                        |
| --------------------- | --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------- |
| Web, i18next          | `format: json` + `framework: i18next`               | Flat JSON per variant plus an i18next driver file                                                                  | [JSON](/string-formats/json), [i18next files](/cli-reference/files#i18next)                                           |
| Web, Vue I18n         | `format: json` + `framework: vue-i18n`              | Flat JSON per variant plus a vue-i18n driver                                                                       | [vue-i18n files](/cli-reference/files#vue-i18n)                                                                       |
| Any ICU-based library | `format: json` + `framework: icu`                   | ICU MessageFormat JSON                                                                                             | [ICU JSON](/string-formats/json#icu-json)                                                                             |
| Flutter               | `format: json` + `framework: arb`                   | ARB files with `@@locale` from each variant's locale code                                                          | [ARB JSON](/string-formats/json#arb-json)                                                                             |
| iOS                   | `format: ios-strings` and `format: ios-stringsdict` | `.strings` and `.stringsdict`, grouped into `.lproj` bundles when `iosLocales` is set, plus a `Ditto.swift` driver | [iOS strings](/string-formats/ios), [iOS locale directories](/cli-reference/files#ditto-generated-files)              |
| Android               | `format: android`                                   | `strings.xml` per variant, in `values-<locale>/` directories when `androidLocales` is set                          | [Android XML](/string-formats/android), [Android locale directories](/cli-reference/files#android-locale-directories) |

The same formats are available from the API without the CLI: `GET /v2/textItems/export?format=<json_i18next | json_vue_i18n | json_icu | arb | ios-strings | ios-stringsdict | android>&variantId=<variant-developer-id>` and the equivalent `/v2/components/export`. See [Export text items](/api-reference/text-items/export-text-items).

### Example: a web app with three locales

```yaml theme={null}
# ditto/config.yml
projects:
  - id: checkout
variants:
  - id: base
  - id: german
  - id: french
outputs:
  - format: json
    framework: i18next
    outDir: ./src/locales
```

Result:

```text theme={null}
src/locales/
├── checkout___base.json
├── checkout___german.json
├── checkout___french.json
└── (i18next driver file that imports the three JSON files, grouped by variant)
```

The driver file is described under [i18next files](/cli-reference/files#i18next); set `type: module` in the output to get ES module syntax instead of CommonJS.

### iOS and Android

`iosLocales` and `androidLocales` map variants to platform locale directories: `.lproj` bundles with a `Ditto.swift` helper on iOS, `values-<locale>/` resources on Android. Complete configs for both are under [Examples](/cli-reference/configuration#examples).

Full option reference: [CLI configuration](/cli-reference/configuration) (`variants`, `iosLocales`, `iosLocalesOutDir`, `androidLocales`, `androidLocalesOutDir`, `outputs`) and [Files](/cli-reference/files).

## Keep it in sync

* Run `pull` in CI or a pre-build step so every build ships the latest approved text. Set `DITTO_TOKEN` as a secret; see [CLI authentication](/cli-reference/authentication#in-ci-or-anywhere-without-a-browser).
* Use the [GitHub Action](/additional-tools/gh-action) to open a pull request automatically when text changes.
* Filter by status (`statuses: [FINAL]`) or by the **integrated** flag so unreviewed translations never reach production. See [`statuses`](/cli-reference/configuration#statuses) and [`integrated`](/cli-reference/configuration#integrated).
* Subscribe to `TextItem_Variant_Text_Changed` and `TextItem_Variants_Changed` [webhooks](/additional-tools/webhooks#text-item-variant-text-change) to react when translations change.

## Ask an agent to do it

With the [MCP connected](/guides/connect-the-mcp), all of the above is available as a conversation:

```text theme={null}
Add a Spanish (es) variant to our workspace, translate the checkout
project's text into Spanish following our Spanish style guide, and update
ditto/config.yml so `pull` fetches base, German, and Spanish.
```

The agent calls `create_variants`, `list_variants`, `update_text_items` (with the variant developer ID) or leaves translation to Magic Translate, `suggest_edit` against the locale-scoped guide, and then edits the config file in your repo.
