🎉 v1.0

Get started

  • Welcome
  • Documentation
  • Pricing
    Soon

Tools

  • I18n MCP
  • CLI
  • CI/CD Integrations
  • Compiler
    Alpha
  • Connect Your Engine

Resources

  • Languages
  • LLM Models
  • Guides

Company

  • Enterprise
  • CareersHiring!
Dashboard

Localization

  • Overview
  • Translation API
  • Web App
  • Mobile App
  • Emails
  • Static Content (e.g. .md, .json)
  • CI/CD Workflows

Static Content Localization

Max PrilutskiyMax Prilutskiy·Updated 1 day ago·3 min read

The Lingo.dev CLI translates static files in your repository - Markdown, MDX, Markdoc, JSON, YAML, subtitles, and more - through a configured localization engine. Point it at your content, run once, and get translated files alongside your source.

Supported Content Types#

Content typeFormatCLI bucketExample path
DocumentationMarkdownmarkdowndocs/[locale]/getting-started.md
DocumentationMDXmdxdocs/[locale]/getting-started.mdx
DocumentationMarkdocmarkdocdocs/[locale]/getting-started.mdoc
Structured dataJSONjsondata/[locale].json
Structured dataYAMLyamldata/[locale].yaml
Blog postsMarkdown / MDXmarkdown / mdxblog/[locale]/post-slug.md
SubtitlesSRTsrtsubs/[locale]/intro.srt
SubtitlesVTTvttsubs/[locale]/intro.vtt
SpreadsheetsCSVcsv-per-localedata/[locale].csv
Config stringsPropertiespropertieslang/[locale].properties
Config stringsGettext POpolocale/[locale]/messages.po
Plain textTXTtxtcontent/[locale]/readme.txt

Prerequisites#

Every CLI run sends content through a localization engine - the configuration that determines which LLM model, glossary, brand voice, and instructions apply. Create one in the Lingo.dev dashboard and generate an API key.

Documentation Sites#

Most documentation frameworks organize translated content in per-locale directories. The CLI's markdown, mdx, and markdoc buckets translate these files while preserving frontmatter, code blocks, and component syntax.

json
{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.15",
  "locale": {
    "source": "en",
    "targets": ["es", "fr", "de", "ja"]
  },
  "buckets": {
    "markdown": {
      "include": ["docs/[locale]/getting-started.md"]
    },
    "mdx": {
      "include": ["docs/[locale]/setup.mdx"]
    }
  }
}

Adjust the include pattern to match your framework's directory convention:

FrameworkLocale directory conventionReference
Docusaurusi18n/[locale]/docusaurus-plugin-content-docs/current/Docusaurus i18n guide
NextraPer-locale pages or JSON dictionariesNextra documentation
Hugocontent/[locale]/Hugo multilingual guide
Astrosrc/content/[locale]/ or JSON dictionariesAstro i18n guide
VitePress[locale]/ directory prefixVitePress i18n
MkDocsPer-locale docs/ with i18n pluginMkDocs i18n plugin

MDX components

The mdx bucket preserves JSX component syntax during translation. Custom components like <Callout>, <Tabs>, and <CodeBlock> pass through unchanged - only the text content inside them is translated.

Structured Data#

JSON and YAML files translate with the json and yaml buckets. Use locked keys to prevent non-translatable values (IDs, URLs, configuration flags) from being modified.

json
{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.15",
  "locale": {
    "source": "en",
    "targets": ["es", "fr", "de", "ja"]
  },
  "buckets": {
    "json": {
      "include": ["content/[locale].json"],
      "lockedKeys": ["id", "slug", "url"]
    },
    "yaml": {
      "include": ["data/[locale].yaml"]
    }
  }
}

For YAML files that use the locale code as the root key (common in Rails and Hugo), use the yaml-root-key bucket instead - it reads from the source locale key and writes to target locale keys within the same file.

Subtitles#

SRT and VTT subtitle files translate with the srt and vtt buckets. The CLI preserves all timing data, cue indices, and formatting tags - only the text content is translated.

json
{
  "$schema": "https://lingo.dev/schema/i18n.json",
  "version": "1.15",
  "locale": {
    "source": "en",
    "targets": ["es", "fr", "de", "ja"]
  },
  "buckets": {
    "srt": {
      "include": ["subs/[locale]/intro.srt"]
    }
  }
}

Working with Large Content#

Static content repositories can contain thousands of files. The CLI handles this efficiently through three mechanisms:

MechanismHow it helps
LockfileTracks SHA-256 fingerprints of source content. Only new or modified files trigger translation on subsequent runs.
Parallel processingDistributes translation across concurrent workers. Configure with run --concurrency 20.
Targeted runsProcess a specific bucket or locale: run --bucket markdown or run --target-locale es.

Next Steps#

Supported Formats
Full reference for all 25+ file formats the CLI can translate
Key Locking
Prevent specific values from being translated
CI/CD Workflows
Automate static content translation on every push
Lockfile
How incremental translation tracking works

Was this page helpful?