Markdown Translation

Translate your Markdown documentation files while preserving code blocks, frontmatter, and inline syntax.

Folder structure

Set markdownPath in your config. PolyCLI expects a subfolder per language inside that path. The source language subfolder must exist; target language subfolders are created automatically.

text
docs/                           ← markdownPath
├── en/                         ← sourceLanguage (you create this)
│   ├── getting-started.md
│   └── api-reference.md
├── it/                         ← created by PolyCLI
│   ├── getting-started.md
│   └── api-reference.md
└── .polycli-md-cache.json      ← commit this file

What is preserved vs. translated

✓ Preserved exactly

  • ---...--- YAML frontmatter
  • Fenced code blocks (``` or ~~~)
  • Inline code spans (`code`)
  • Link and image URLs — (url) part only
  • Inline HTML tags
  • Blank line separators between blocks

✎ Translated

  • Headings (# H1, ## H2, ...)
  • Paragraphs
  • List items (ordered and unordered)
  • Blockquotes
  • Link text — [text] part only

Before and after

docs/en/guide.md (source)
---
title: Getting Started
---

# Welcome to PolyCLI

Install the CLI with `npm install -g @polycli/cli`.

Visit [our documentation](https://app.polycli.dev/docs) for more details.

```bash
polycli init
```
docs/it/guide.md (output)
---
title: Getting Started
---

# Benvenuto su PolyCLI

Installa la CLI con `npm install -g @polycli/cli`.

Visita [la nostra documentazione](https://app.polycli.dev/docs) per ulteriori dettagli.

```bash
polycli init
```

The YAML frontmatter and code fence are untouched. The link URL is unchanged. The inline code span (`npm install…`) is preserved as-is.

Glossary protection in Markdown

Terms listed in glossary.doNotTranslate are tokenized in Markdown content before translation and restored verbatim afterward — exactly as they are for JSON files. Brand names, CLI commands, and other protected terms will never be altered in your translated Markdown output.

Sentence-level caching

PolyCLI does not cache translations at the paragraph level — it caches at the sentence level. Each translatable block is split into individual sentences (or lines, for lists and blockquotes) before being hashed and stored.

This means that when you edit a paragraph, only the sentences you actually changed consume credits. Unchanged sentences are reused from the cache and stitched back together with their translations automatically.

Cache file

PolyCLI stores the translation memory in .polycli-md-cache.json inside your markdownPath. The cache maps each sentence's content hash to its translated text, per language. Commit this file — without it, every run re-translates all content from scratch.

Commit .polycli-md-cache.json to version control. It is the translation memory for Markdown files. Deleting or gitignoring it will cause all content to be re-translated on the next run and credited accordingly.