Skip to main content
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 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 and 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.
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.

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:
  • 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). More detail: 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. The Integrated toggle in a text item's details panel

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. Project menu with the Development integration entry Project developer integration modal showing the project developer ID Text items and library components: select the item and edit the Developer ID field in the details panel. Editing a text item's developer ID 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. The developer ID bulk editor Library folders: open the folder’s parent, choose Folder properties… from the folder’s menu, and edit the Developer ID in the details panel. Editing a library folder's developer ID Variants: open Variants, select a variant, and edit the Developer ID in the details panel. Editing a variant's developer ID

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

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.

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.

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.

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.