Translation pipeline notes
How the 12 target locales are produced, and the one rule that has to live outside this repository.Where translation is configured
That last row is the important one.
npx lingo.dev@latest run with
LINGO_API_KEY set routes every string through our localization engine on
the Lingo.dev platform. The engine applies its layers in order:
- Glossary (highest): exact term mappings
- Rules: locale-scoped linguistic conventions
- Brand voice: tone, formality, register
- Model chain: which model handles each locale pair, with fallbacks
- AI reviewers: asynchronous quality checks
i18n.json. The config schema (version 1.10)
has no field for instructions, glossaries or brand voice; its only prompt-ish
field is provider.prompt, which applies solely to a bring-your-own-key
provider (openai, anthropic, google, ollama, openrouter, mistral).
Adding a provider block would take us off the engine and lose the
glossary, brand voices and translation memory along with it. Do not do that to
get at the prompt.
The no-dashes rule
House style bans em dashes (U+2014) and en dashes (U+2013) everywhere. English is clean, but the engine reintroduces dashes while translating: as of 2026-09-16 a sweep removed 1543 of them across 545 files in all 12 locales. Sweeping the locale files fixes today’s output only. The locale directories are generated, so the next time the English source of a string changes, the engine retranslates it and can put the dash straight back. The durable fix is a rule on the engine. Add it as a rule (the “locale-scoped linguistic conventions” layer), applied to every target locale, not as a glossary entry, because a glossary maps terms and this is a punctuation convention. Suggested wording:Never use an em dash (U+2014, —) or an en dash (U+2013, –) in any output. This applies to body text, headings, link text, image alt text, table cells and YAML frontmatter values alike. Where the source or a natural translation would use one, rephrase using the target language’s own conventions: a comma, a colon, parentheses, a conjunction, or two sentences. Never substitute an ASCII hyphen (-) for a dash. Numeric and date ranges are spelled out with the target language’s word for “to” rather than a dash.
How to apply it
The engine is configured through the Lingo.dev MCP server, which can create and update rules, glossaries and brand voices conversationally, or through the Lingo.dev dashboard. The MCP server is not wired into this repository’s tooling, so this is a one-time manual step by someone with access to the Scribe organization on Lingo.dev. Ask the assistant to “add a rule to every locale on the Scribe engine: never emit em dashes or en dashes, rephrase instead”, and paste the wording above. Caveat worth keeping in mind: an engine rule steers a language model, it does not hard-guarantee a character never appears. That is why the repo also keeps a checker.The guard
scripts/check-dashes.mjs runs last in translate.yml, with if: always().
en/**and the other hand-written pages: hard failure. English is authored by people, so a dash there is a real style bug with an owner.- The 12 locale directories: report only. Blocking would be a deadlock. The
commit step in
translate.ymlonly runs when the preceding steps succeed, so failing on a generated file means the refreshed translations are never committed, and since the dashes come back from the engine, that failure repeats every run and freezes all 12 locales on an older build. Locale hits become GitHub warning annotations instead.
node scripts/check-dashes.mjs --strict locally to fail on locales too,
which is what you want when doing a deliberate sweep.
scripts/check-mdx.mjs additionally parses each page’s YAML frontmatter. The
MDX compiler treats the --- block as opaque, so a page with unreadable
frontmatter compiles fine here and then fails the Mintlify build. The specific
trap when removing dashes: replacing a dash with ": " inside an unquoted
plain scalar turns description: Install in one click: do this into a mapping
value nested in a mapping value, which is a YAML error. Use a comma, or quote
the whole scalar.