> ## 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.

# Configuration

> Setting what text and formats the CLI pulls down

## Overview

The `config.yml` file is the source of truth for a given directory about how the CLI should fetch and store data from Ditto based on the specified properties. It includes information about which Ditto components the CLI should pull text from, the string file formats, and more.

This is the default configuration file that is generated the first time that the CLI is run in a given directory:

```yml theme={null}
projects: []
variants: []
components:
  folders: []
outputs:
	- format: json
		framework: i18next
```

## Supported Properties

Listed below are each of the properties that you can specify in your CLI config.

```typescript theme={null}
// Individual property definitions
type ProjectConfig = { id: DeveloperId };
type ComponentFolderConfig = {
  id: "root" | DeveloperId,
  excludeNestedFolders?: boolean
}
type VariantConfig = { id: "all" | "base" | DeveloperId }
type TagsFilter = {
  values: string[],
  operator?: "AND" | "OR"
}
type OutputConfig = {
  format: "json" | "android" | "ios-strings" | "ios-stringsdict",
  framework: "i18next" | "vue-i18n",
  projects?: ProjectConfig,
  components?: ComponentsConfig,
  variants?: VariantsConfig,
  statuses?: TextStatus[],
  integrated?: boolean,
  tags?: TagsFilter,
  outDir?: string
}
type TextStatus = "NONE" | "WIP" | "REVIEW" | "FINAL"

// Full config object
{
  projects?: ProjectConfig[],
  components?: {
    folders?: ComponentFolderConfig[]
  },
  variants?: VariantConfig[],
  statuses?: TextStatus[],
  integrated?: boolean,
  tags?: TagsFilter,
  richText?: “html” | false,
  outDir?: string,
  outputs: OutputConfig[],
}
```

### `projects`

An array of Developer IDs of the projects to pull from. If provided an empty array, will pull text from all projects. The text from each included project will be written to its own json file, per variant. For more details, see the `filter.projects` param for `GET /v2/textItems` .

**Required: false**. If omitted, will not pull text from any projects.

**Example:** The following will pull in all text from the projects with Developer ID "project-1" and "project-2"

```yaml theme={null}
projects:
  - id: project-1
  - id: project-2
```

### `components`

An object with a single property, `folders`, which takes a list of component folders to pull text from. If provided `{}` or `folders: []`, will pull all components from all folders. Unlike project text, all fetched components will be written to a single file per variant, regardless of the specified folder configuration.

**Required: false**. If omitted, will not pull any components.

By default, will return all components within the specified folders, including those found inside any subfolders. If you do not want to include components within subfolders, add `excludeNestedFolders: true` to that folder's specification.

To pull top-level components (those not inside a folder), you can use the reserved word `"root"` as the folder id. This is best used in combination with `excludeNestedFolders: true`.

**Example:** The following will return all top-level components as well as all components inside "folder-1" along with all components inside all folders inside "folder-1" (no matter how deeply nested). For more details, see the `filter.folders` param for `GET /v2/components` .

```yaml theme={null}
components:
  folders:
    - id: root
      excludeNestedFolders: true
    - id: folder-1
```

### `variants`

An array of variants to return. The value will be applied to both projects and components.

By default, or if passed `[]`, will return base text only. Provide `id: all` to return base and all variants. Or, you may provide a list of the Developer IDs of the specific variants you wish to return; in this case, you must explicitly include `base` in the list to fetch base text. For more details, see the `filter.variants` param for `GET /v2/textItems` and `GET /v2/components` .

**Required: false**. If omitted, will return base text only.

**Examples**:

```yml theme={null}
# Returns base text only
variants: []

# Returns base text and all variants
variants:
  - id: all

# Returns french and spanish variant text
variants:
  - id: french
  - id: spanish

# Returns base text, french and spanish variants
variants:
  - id: base
  - id: french
  - id: spanish
```

### `statuses`

An array of statuses to return. The value will be applied to both projects and components.

By default, or if passed `[]`, will return all statuses. Provide an array of statuses to selectively filter values you wish to have returned.
When the statuses filter is used with the variant filter, only variants that match the variant and status filters AND are associated with base text that matches the status filter will be returned.
For more details, see the `filter.statuses` param for `GET /v2/textItems` and `GET /v2/components` .

**Required: false**. If omitted, will return all statuses.

**Examples**:

```yml theme={null}
# Returns without any filtering
statuses: []

# Returns base text that has "FINAL" or "WIP" statuses
variants: []
statuses:
  - "FINAL"
  - "WIP"

# Returns base text that has "FINAL" or "WIP" statuses and any related variant text of that base text that also has "FINAL" or "WIP" statuses
variants:
  - id: all
statuses:
  - "FINAL"
  - "WIP"

# Returns spanish variant text that has a "FINAL" or "WIP" status and has base text that also has a "FINAL" or "WIP" status
variants:
  - id: spanish
statuses:
  - "FINAL"
  - "WIP"
```

### `tags`

An object specifying one or more tags to filter by. The value will be applied to both projects and components.

The `values` field is an array of tag strings. The optional `operator` field controls how multiple tags are combined: `"AND"` returns only items with all specified tags, while `"OR"` (the default) returns items with any of the specified tags.

**Required: false**. If omitted, will return all items regardless of tags.

**Examples**:

```yml theme={null}
# Returns items tagged with "tag-1" or "tag-2"
tags:
  values:
    - "tag-1"
    - "tag-2"

# Returns only items tagged with both "tag-1" and "tag-2"
tags:
  values:
    - "tag-1"
    - "tag-2"
  operator: "AND"
```

### `integrated`

A boolean value (true | false) to filter the results only to those items whose `integrated` property matches the provided value. The value will be applied to all projects and components.

**Required: false**. If omitted, will return all items, regardless of integration status.

### `richText: "html" | false`

Flag to determine if the pulled text is represented as plain text or rich text (in HTML format).

**Required: false**. If omitted, will return plain text only.

```typescript theme={null}
// richText: false
{
  "dev-id-1": "This is awesome text",
  "dev-id-2": "This is other text. It has two sentences."
}

// richText: html
{
  "dev-id-1": "This is <strong>awesome</strong> text",
  "dev-id-2": "<p>This is other text.</p><p>It has two sentences</p>"
}
```

### `outDir: string`

The relative path from where the CLI is run to the directory the generated files should be created in. If the provided directory does not exist, it will be created automatically.

**Required: false.** If omitted, the default location is `./ditto`.

### `iosLocales`

An array that maps Ditto variant IDs to [iOS locale IDs](https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPInternational/LanguageandLocaleIDs/LanguageandLocaleIDs.html). When used in conjunction with `ios-strings` or `ios-stringsdict` output formats, this configuration enables the CLI to generate a `Ditto.swift` driver file and organize locale files into the standard iOS `.lproj` localization bundles.

**Required: false**. If omitted, iOS formats will be generated without locale-specific directory organization.

Each entry in the array maps a variant ID to its corresponding locale code. The variant ID must match a variant defined in your `variants` configuration, or be included via variants `id: all`. The iOS locale code should be a valid iOS locale identifier (e.g., `en`, `es`, `fr`, `de`).

**Behavior:**

* When `iosLocales` is configured and used with `ios-strings` or `ios-stringsdict` formats, the CLI generates a `Ditto.swift` driver file
* The `Ditto.swift` file is placed at the root-level `outDir` (`./ditto` if not configured) and NOT at the `ios-strings` or `ios-stringsdict` output `outDir`
* Variants mapped in `iosLocales` are written to `<locale>.lproj` directories
* Both `.strings` and `.stringsdict` files are placed within the same `.lproj` directories
* Variants not mapped in `iosLocales` will be written to the output directory with their variant suffix (e.g., `my_project___french.strings`)

**Example:** Basic configuration with matching output directory

```yaml theme={null}
iosLocales:
  - base: en
  - spanish: es
  - french: fr

outputs:
  - format: ios-strings
  - format: ios-stringsdict
```

This configuration will generate:

```
./ditto/
├── Ditto.swift
├── en.lproj/
│   ├── my_project.strings
│   ├── my_project.stringsdict
│   ├── components.strings
│   └── components.stringsdict
├── es.lproj/
│   ├── my_project.strings
│   ├── my_project.stringsdict
│   ├── components.strings
│   └── components.stringsdict
└── fr.lproj/
    ├── my_project.strings
    ├── my_project.stringsdict
    ├── components.strings
    └── components.stringsdict
```

**Example:** With root-level `outDir` and multiple iOS formats

```yaml theme={null}
outDir: "./my-text"

iosLocales:
  - base: en
  - spanish: es
  - french: fr

outputs:
  - format: ios-strings
  - format: ios-stringsdict
```

The `Ditto.swift` file and `.lproj` directories will be placed in `./my-text/`, with both `.strings` and `.stringsdict` files organized within each locale directory.

**Example:** Mismatched `outDir` with unmapped variants

When an output specifies a different `outDir` than where mapped locales are written, only variants not mapped in `iosLocales` will be written to that output's directory:

```yaml theme={null}
outDir: "./my-text"

variants:
  - id: base
  - id: spanish
  - id: french

iosLocales:
  - base: en
  - spanish: es

outputs:
  - format: ios-strings
    outDir: "./ios"
```

This will generate:

```
./my-text/
├── Ditto.swift
├── en.lproj/
│   ├── my_project.strings
│   ├── components.strings
│   └── ...
├── es.lproj/
│   ├── my_project.strings
│   ├── components.strings
│   └── ...
└── ios/
    ├── my_project___french.strings
    └── components___french.strings
```

In this case, `base` and `spanish` variants are mapped to iOS locales and written to `.lproj` directories in `./my-text/`, while the `french` variant (not mapped in `iosLocales`) is written to `./ios/` with its variant suffix.

### `outputs`

An array of output configurations. Each one will lead to its own set of files being generated in the specified location.

**format**: `json | android | ios-strings | ios-stringsdict` - Required. The file format for the exported data. For details on each format's file structure, see the [Files documentation](/cli-reference/files).

**framework**: `i18next | vue-i18n` - Optional. If provided, will generate additional helper files to assist in integrating the Ditto data into the specific framework. See [frameworks](/cli-reference/files#format-specific-files) section for more details.

All top-level fields can also be defined within each provided output, with the exception of `iosLocales`. Providing a value at the output level will override any fields defined at the global level. For example, if `outDir` is defined at the root of the config to be `./customPath1`, and is set to `./customPath2` within an output, the files generated by that specific output will be created within the `./customPath2` directory, while any other outputs will go to `./customPath1`.

Here is a much more complex example:

```yaml theme={null}
projects:
  - id: my-project
components:
  folders:
    - id: root
      excludeNestedFolders: true
variants: []
richText: html
outDir: ./ditto/top
outputs:
  - format: json
  - format: json
    framework: vue-i18n
    variants:
      - id: french
    outDir: ./ditto/french
  - format: json
    framework: i18next
    outDir: ./ditto/i18next
    type: module
    projects: []
    components:
      - id: special-folder
    variants:
      - id: french
      - id: spanish
      - id: base
    richText: false
```

The config file above will work as follows:

1. There are three outputs specified, so the query will run three times, each with different filters
2. The first output has no special overrides, so it will create all the `json` files for the top-level query — just the base text from the project with Developer ID “my-project” along with top-level components. These files will be saved to the directory `./ditto/top` with rich text enabled.
3. The second output contains some overrides. This will still apply the same projects and components filters, but will request the french variant and save its files to `./ditto/french` with rich text enabled. It will also create the `vue-i18n` driver files.
4. The third output overrides all of the filters. It will query for the french, spanish and base variants from all projects and all components inside the folder with Developer ID "special-folder", including all components in any nested folders. It will also create the `i18next` driver file(s). All of these files will be saved to the `./ditto/i18next` directory and will only include plaintext.

```shell Output files for example config theme={null}
.
└── ditto/
    └── top/
        ├── my_project__base.json
        └── components__base.json
    └── french/
        ├── my_project__french.json
        ├── components__french.json
        ├── variables.json
        └── index.js
    └── i18next/
        ├── my_project__french.json
        ├── my_project__base.json
        ├── my_project__french.json
        ├── my_project__spanish.json
        ├── my_other_project__base.json
        ├── my_other_project__french.json
        ├── my_other_project__spanish.json
        ├── components__base.json
        ├── components__french.json
        ├── components__spanish.json
        ├── variables.json
        └── index.js
```
