|
Documentation
Book a DemoPlatform
PlatformMCPCLI
APIWorkflows
GuidesChangelog

Overview

  • @lingo.dev/cli

Getting started

  • Quickstart
  • Configuration

Reference

  • lingo push
  • lingo pull
  • Other commands
  • lingo purge

Configuration

  • Key controls
  • Formats
  • Locales

Guides

  • Adding a locale
  • Existing translations
  • Retranslation
  • Translator notes
  • Runs, state, and recovery
  • CI/CD
  • Monorepos
  • Large projects

Looking for the older CLI (v0)? See the legacy CLI docs

Formats

The CLI translates seventeen file formats. The format is inferred from the file extension; set format on a files[] entry to override it — or for the two formats that always need it (yaml-openapi, android).

FormatExtensionsformat valueNotes
JSON.jsonjsonKey/value. Supports key controls.
JSONC.jsoncjsoncJSON with comments. Comments survive and double as translator notes.
YAML.yaml, .ymlyamlGeneric YAML. Every string value is translated; keys and structure preserved.
OpenAPI YAML.yaml, .ymlyaml-openapiOpenAPI specs. Set format explicitly — plain .yaml auto-detects as yaml.
Markdown.mdmdProse translated; frontmatter opt-in.
MDX.mdxmdxMarkdown + JSX. Component props opt-in.
Markdoc.mdocmarkdocMarkdown + tags. Frontmatter + tag attributes.
TypeScript.ts, .mts, .ctstypescriptLocale modules (export default { … }). String literals translated; code preserved.
Gettext PO.popomsgstr translated; msgid, comments, and headers preserved.
Flutter ARB.arbflutterString values translated; @-metadata and {placeholders} preserved.
Android.xmlandroidstrings.xml. Set format explicitly — .xml isn't auto-detected.
Xcode strings.stringsxcode-stringsValues translated; keys preserved.
Xcode String Catalog.xcstringsxcode-xcstringsOne file holds every locale — targets are written back into the same file (see below).
Xcode stringsdict.stringsdictxcode-stringsdictPlural strings translated; format control keys preserved.
XLIFF.xlf, .xliffxliff<source> kept, <target> written per unit. Versions 1.2 and 2.0.
SubRip.srtsrtSubtitle text translated; indices and timecodes untouched.
PHP.phpphpLaravel return [ … ]. String values translated; keys, numbers, and structure preserved.

See it end to end

The demo project ships one file per format with the exact config each needs. Clone it with npx degit lingodotdev/lingo.dev/demo/new-cli my-lingo-demo and run a push.

bash
npx degit lingodotdev/lingo.dev/demo/new-cli my-lingo-demo
cd my-lingo-demo

JSON and JSONC#

Plain key/value translation. Every string value is translated unless a key control says otherwise.

json
{ "pattern": "content/en/app.json", "lockedKeys": ["meta.version"] }

JSONC additionally preserves comments, which the engine reads as context — see translator notes.

json
{ "pattern": "content/en/settings.jsonc", "preservedKeys": ["featureFlags"] }

Markdown, MDX, and Markdoc#

Body prose is translated by default. Frontmatter and embedded components are not translated unless you opt in.

Frontmatter#

List the frontmatter fields to translate with translateFrontmatterFields:

json
{
  "pattern": "content/en/guide.md",
  "translateFrontmatterFields": ["title", "description"]
}

MDX component props#

For MDX, translate specific props on specific components with translateComponentProps:

json
{
  "pattern": "content/en/landing.mdx",
  "translateFrontmatterFields": ["title"],
  "translateComponentProps": [{ "component": ["Hero", "Callout"], "props": ["title", "body"] }]
}

This translates the title and body props on <Hero> and <Callout> and leaves all other props untouched.

Markdoc#

Markdoc works like Markdown, with frontmatter and tag attributes preserved:

json
{
  "pattern": "content/en/changelog.mdoc",
  "translateFrontmatterFields": ["title"]
}

YAML#

Generic YAML is auto-detected from .yaml/.yml — every string value is translated, keys and structure preserved:

json
{ "pattern": "content/en/strings.yaml" }

OpenAPI specs are a special case: they share the .yaml extension but need an explicit format so the engine translates only human-facing fields (summaries, descriptions) and leaves schema keys, paths, and operation IDs intact:

json
{ "pattern": "content/en/api.yaml", "format": "yaml-openapi" }

App and framework formats#

PO, Flutter ARB, Xcode .strings, Xcode .stringsdict, TypeScript locale modules, XLIFF, SubRip, and PHP all follow the same rule: translatable text is translated, everything structural is preserved (keys, IDs, metadata, placeholders, timecodes, code, formatting). Each is auto-detected from its extension — just point a pattern at the source file:

json
{ "pattern": "lib/l10n/app_en.arb" }
{ "pattern": "locales/en.po" }
{ "pattern": "Localizable.strings" }
{ "pattern": "l10n/en.xlf" }

One needs an explicit format because its extension is too ambiguous to auto-detect:

json
{ "pattern": "res/values/strings.xml", "format": "android" }

Xcode String Catalogs#

A .xcstrings (String Catalog) file holds all locales in a single file. There's no per-locale output path — the CLI reads the source locale and writes every target back into the same file:

json
{ "pattern": "Localizable.xcstrings" }

Output paths#

For every format except the String Catalog, targets are written by substituting the locale segment of the source pattern — content/en/app.json → content/de/app.json. Keep the source locale in the path so the CLI knows where targets go. See Configuration.

Coming from the legacy CLI?#

Most of the legacy CLI's formats have landed in the current CLI (PO, XLIFF, Android/Xcode strings, Flutter ARB, and more — see the table above). A few less-common formats (e.g. CSV, HTML, MJML, .properties) aren't supported yet; until yours lands, the legacy CLI docs cover it.

Was this page helpful?

Max PrilutskiyMax Prilutskiy·Updated 4 days ago·4 min read