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

# Key concepts

> Definitions for Ditto's data model: projects, text items, library components, developer IDs, style guides, variants, variables, plurals, and scans.

This page defines the terms the CLI, API, MCP tools, and guides use.

## Projects, text items, and the component library

* A **project** holds the text for one product surface, usually one Figma file or one feature. Text inside a project is a set of **text items**. A text item is one string plus its metadata: status, tags, notes, assignee, character limit, variants, plurals, and the Figma layers it is linked to. Editing a text item updates every linked layer.
* **Blocks** group text items within a project, in display order. They are how a project's text is organized on screen; the API and MCP address them by developer ID.
* The **component library** is one per workspace. A **library component** is reusable text: attach it to text items in any number of projects and editing the component updates every instance. Components live in **folders**, which can nest. A [scan](/get-started/scan-your-repo) creates library components, in folders, from the strings in your codebase.
* Text items and library components share the same developer ID space; a component and its attached instances share one developer ID.

For designers' view of these concepts, see [Text items and linking](https://help.dittowords.com/en/articles/11502480-text-items-and-linking) and [Component library](https://help.dittowords.com/en/articles/11502584-component-library) in the help center.

## Developer IDs

Developer IDs are unique, usually human-readable identifiers for projects, text items, library components, component folders, blocks, variables, variants, and style guides. They are the key you reference in code and the key you pass to the API, CLI, and MCP tools.

Developer IDs are generated when an item is created: projects, components, and folders from their name, text items from their text. To keep references stable, Ditto never changes a developer ID automatically when the underlying data changes. Editing a text item's text does not change its developer ID.

You can edit a developer ID by hand at any time.

<Warning>
  If you change a developer ID in Ditto, update every reference to it in your application. Make such edits before an item is in use in code.
</Warning>

### Uniqueness

Developer IDs for a given entity type are unique within a workspace. Two projects cannot share an ID, and two pieces of text cannot share an ID, but a project and a text item may.

Text items and library components draw from the same pool: a library component and an unrelated text item cannot share a developer ID, and similar text items in different projects cannot either, with one exception: a library component and the text items attached to it all share the component's developer ID, because their content is kept identical.

**Example.** A library component has developer ID `hello`. Two projects each get a text item with the text "hello"; they are assigned `hello-1` and `hello-2`. Attaching both to the component gives all three the developer ID `hello`.

### Configuration

Developer IDs are generated and validated against a workspace-wide **Developer ID configuration**, editable on the [Developers page](https://app.dittowords.com/developers/configure-dev-ids):

* **Allowed characters**: the set of characters permitted in a developer ID.
* **Character replacement**: an ordered list of substring replacements applied to the source text during generation.
* **Casing adjustment**: optionally transform the case of the source text. Options: lowercase, UPPERCASE, camelCase, PascalCase.
* **Maximum length**: the maximum number of characters. Deduplication may append a short suffix *after* truncation, so generated IDs can exceed the limit by a few characters. If your system has a hard limit, set the maximum three or more characters below it. Manual edits over the limit are rejected.

A scan proposes this configuration for you from the keys it finds in your code (see [What a scan produces](#what-a-scan-produces)). More detail: [Developer ID configuration](https://help.dittowords.com/en/articles/14529160-developer-id-configuration).

### Marking text as integrated

Text items and library components can be marked **integrated** to signal that their developer ID is in use in code: changing the ID would be a breaking change, and changing the text changes production copy.

The flag is a filter on every API endpoint that fetches text, on the CLI config (`integrated: true`), and on every webhook payload (`integrated: boolean`), so you can limit what reaches your codebase to text that is known to be in use.

<img src="https://mintcdn.com/ditto/dDYr8fLNLi9vWSv6/images/dev-id-integrated-toggle.png?fit=max&auto=format&n=dDYr8fLNLi9vWSv6&q=85&s=6611b2ec1d9ec9dbb293b524c4fc8ac3" alt="The Integrated toggle in a text item's details panel" style={{ width: "100%" }} width="383" height="146" data-path="images/dev-id-integrated-toggle.png" />

### Where to find and edit developer IDs

**Projects**: open the project's main menu (top right of the project in the web app) and choose **Development integration**.

<img src="https://mintcdn.com/ditto/pXBmKmaeW4wg1sef/images/project-menu.png?fit=max&auto=format&n=pXBmKmaeW4wg1sef&q=85&s=eecd0d72bb4cc22d6d9d8923d0ec8f49" alt="Project menu with the Development integration entry" style={{ width: "100%" }} width="598" height="626" data-path="images/project-menu.png" />

<img src="https://mintcdn.com/ditto/pXBmKmaeW4wg1sef/images/project-dev-integration-modal.png?fit=max&auto=format&n=pXBmKmaeW4wg1sef&q=85&s=6a5bf52d92416a6bdf926de0f3ef041a" alt="Project developer integration modal showing the project developer ID" style={{ width: "100%" }} width="848" height="446" data-path="images/project-dev-integration-modal.png" />

**Text items and library components**: select the item and edit the **Developer ID** field in the details panel.

<img src="https://mintcdn.com/ditto/7aMEipg7bpvcHX8V/images/dev-id-edit-text-item.png?fit=max&auto=format&n=7aMEipg7bpvcHX8V&q=85&s=b26b634a5d45f251f3eefba100a66100" alt="Editing a text item's developer ID" width="1918" height="1274" data-path="images/dev-id-edit-text-item.png" />

Select several items to open the **Bulk editor**, which edits many IDs at once and supports operations such as adding a prefix. Details: [Developer ID bulk editor](https://help.dittowords.com/en/articles/14792979-developer-id-bulk-editor).

<img src="https://mintcdn.com/ditto/7aMEipg7bpvcHX8V/images/dev-id-bulk-editor.png?fit=max&auto=format&n=7aMEipg7bpvcHX8V&q=85&s=c4cd2342a4d353da5e2cdfc4a58cb61e" alt="The developer ID bulk editor" width="929" height="634" data-path="images/dev-id-bulk-editor.png" />

**Library folders**: open the folder's parent, choose **Folder properties…** from the folder's menu, and edit the **Developer ID** in the details panel.

<img src="https://mintcdn.com/ditto/pXBmKmaeW4wg1sef/images/library-folder-dev-ids.gif?s=97a5dbf0aeea0eaf02dfd4af980d26ed" alt="Editing a library folder's developer ID" style={{ width: "100%" }} width="1328" height="774" data-path="images/library-folder-dev-ids.gif" />

**Variants**: open [Variants](https://app.dittowords.com/variants), select a variant, and edit the **Developer ID** in the details panel.

<img src="https://mintcdn.com/ditto/7aMEipg7bpvcHX8V/images/dev-id-variant.png?fit=max&auto=format&n=7aMEipg7bpvcHX8V&q=85&s=008ec03e66c2413ba96439c4b0bc0726" alt="Editing a variant's developer ID" width="2516" height="1042" data-path="images/dev-id-variant.png" />

## Style guides and rules

A **style guide** is a named ruleset for how your product's text reads. A workspace can have several. Each has a description and an **enabled by default** flag; enabled-by-default guides apply to every project unless a project turns them off.

* A style guide is divided into **sections**, each of kind `rules` or `wordlist`.
* A **rule** (in a `rules` section) has a `name`, a `description` of what to do, one or more `examples` as from → to pairs, optional `tags` that limit it to text carrying those tags, and an `enabled` flag.
* A **word list entry** (in a `wordlist` section) has a preferred `term`, `disallowed` alternatives, and a `description`.
* A style guide can be **scoped to a variant with a locale code**, which is how locale-specific rules (formality, terminology) are attached to a language.

Agents fetch rules with `get_styleguide_rules` and check text with `suggest_edit`; the [PR review bot](/additional-tools/github-pr-review-bot) enforces them on pull requests; the Ditto app applies them through Magic Edit and Magic Translate. After a scan, Ditto drafts a starter style guide from your strings; see [Get a first style guide from your scan](/get-started/scan-your-repo#get-a-first-style-guide).

## Variants and locales

A **variant** is a named alternative for a text item's text. Every text item and library component has base text and any number of variant texts. Variants are workspace-level objects with a name, description, developer ID, and optional **locale code**.

A **locale** is simply a variant with a locale code (`de-DE`, `fr`, `es-419`). Ditto's localization features key on it: Magic Translate uses it as the target language, locale-scoped style guides attach to it, and the CLI's `iosLocales` and `androidLocales` map it to platform locale directories. At most one variant per workspace holds a given locale code.

Variants without a locale code cover other uses, such as tone or A/B copy.

The **base locale** is the language of your base text, set in a project's or the library's **Variant & locale settings**. Set it when your source copy is not English.

How to add locales, get translations, and pull localized files: [Set up localization](/guides/set-up-localization).

## Variables

**Variables** are reusable placeholders for values your app fills in at runtime. Write one into text as `{{variable_name}}`. Each variable has a type: `string` or `number` (with an example and optional fallback), `hyperlink` (link text and URL), `list` (a set of possible values), or `map` (key-value pairs).

A variable's name is its developer ID: letters, numbers, and underscores, unique in the workspace.

The API, CLI, and manual exports render variables in each string format's native placeholder syntax (for example `{username}` in ICU JSON, `%1$@` in iOS `.strings`, `<xliff:g>` in Android XML). A scan detects the variables in your strings and creates them. More detail: [Variables](https://help.dittowords.com/en/articles/11657688-variables).

## Plurals

A text item can define **plural forms** (`zero`, `one`, `two`, `few`, `many`, `other`) so your app renders different copy for different counts: "No results", "1 result", "10 results".

The API returns the base form (`pluralForm: null`) and each defined plural form as separate objects. Following i18next conventions, each plural form's developer ID is the text item's developer ID with a suffix, for example `results_one`. In your code you reference the main developer ID and pass a `count`; the i18n library picks the form.

Plurals can contain variables and can be translated per variant. Each string format renders plurals natively (`.stringsdict` on iOS, `<plurals>` on Android, `{count, plural, …}` in ICU). More detail: [Plurals](https://help.dittowords.com/en/articles/13460485-plurals).

## Tags and statuses

* **Tags** are labels on text items and library components. Style guide rules can be limited to tagged text, and the API, CLI, and `search_ditto_text` filter by tag. Only tags that already exist in the workspace can be used on a rule; `get_workspace_tags` lists them. A scan proposes a tag vocabulary for your strings.
* **Statuses** track text through your workflow, from first draft to ready to ship. The default set is `NONE`, `WIP`, `REVIEW`, `FINAL`, but a workspace can rename or replace it, so call `list_statuses` (MCP) or `GET /v2/statuses` before setting or filtering by status. Filtering `pull` to `FINAL` keeps unreviewed text out of production.

## What a scan produces

`npx @dittowords/cli scan <path>` extracts **candidate strings** from your code and uploads them for review. A candidate is one string with where it was found, how it was found (markup text, an attribute value, a value in a localization resource file, or another string position), its translation key and locale if it came from a localization file, and a few surrounding lines of source.

Ditto then:

1. **Classifies** each candidate as user-facing or not.
2. **Proposes a content system** for the user-facing strings: a tag vocabulary, a naming scheme for components, a folder structure, the variants and locales found in your translation files, and a developer ID configuration derived from your existing keys. You review and adjust this before anything is created.
3. **Creates** the library components (in folders, with tags), the variables they use, and one variant per locale.
4. **Drafts a style guide** from a sample of the strings, for you to review and enable.

Details and commands: [Scan your repo](/get-started/scan-your-repo).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.