Страницы · Mark It Down
Internationalization (i18n)
Mark It Down ships with translations for English (default) plus Spanish, French, German, and Arabic (RTL). VSCode picks the locale from its own UI language setting; you don't need to configure the extension separately.
What's localised
- Manifest strings — command titles, view names, settings descriptions,
the activity-bar container, the "no notes yet" welcome message.
Source of truth:
package.nls.json(English fallback) + per-localepackage.nls.<lang>.json. - Runtime strings — status-bar labels, empty-state hints, exporter
notifications. Source of truth:
l10n/bundle.l10n.json+ per-localel10n/bundle.l10n.<lang>.json.
Locales shipped
| Code | Language | Notes |
|---|---|---|
| (default) | English | Source of truth |
| es | Spanish | Full coverage |
| fr | French | Full coverage |
| de | German | Full coverage |
| ar | Arabic | Full coverage; RTL handled natively by VSCode |
For RTL: VSCode's locale loader sets dir="rtl" on the workbench
automatically when the active language is Arabic. Sidebar, modals, and
status bar mirror without code changes. The custom markdown editor
webview inherits the workbench direction so headings, lists, and tables
render right-to-left.
How VSCode resolves locales
- The user picks a language via
Configure Display Language(it downloads the matching VSCode language pack). - On extension load, VSCode looks for
package.nls.<lang>.jsonalongsidepackage.jsonand substitutes%key%references in the manifest. - Runtime strings resolve via
vscode.l10n.t(key, …)by readingl10n/bundle.l10n.<lang>.json. Thel10nfield inpackage.jsonpoints the resolver at this directory. - Missing keys fall back to the English source — there's no
[Untranslated]marker shown to the user.
Calling t() in code
The wrapper around vscode.l10n.t keeps call sites stable across
runtime changes and makes the bundle key easy to grep.
Positional placeholders use {0}, {1} … in the bundle string and the
extra args fill them in order. Don't concatenate translated strings —
build a single bundle key per sentence so locales can re-order it.
Parity check
scripts/check-i18n.mjs enforces that every package.nls.<lang>.json
and l10n/bundle.l10n.<lang>.json has exactly the same keys as the
English source — no missing keys, no extras. CI runs it on every PR via
.github/workflows/ci.yml.
Run locally:
$ pnpm check-i18nA clean output reads i18n parity OK — checked 8 locale file(s).
Adding a new locale
- Copy
package.nls.jsontopackage.nls.<lang>.jsonand translate each value. - Copy
l10n/bundle.l10n.jsontol10n/bundle.l10n.<lang>.jsonand translate each value. - Run
npm run check-i18n— fix any reported discrepancies. - Run
npm test— the parity vitest intests/unit/i18n/parity.test.tsasserts the same invariant. - Update this doc's "Locales shipped" table.
VSCode auto-discovers the new locale on the next launch — no manifest declaration needed.
Adding a new key
- Add it to
package.nls.json(orl10n/bundle.l10n.json) first. - Add the matching key to every
<lang>file in that family. - Reference it in the manifest as
%key%or in code viat('key'). - The parity check + vitest will catch any locale you forgot.
Testing
$ pnpm dlx vitest run tests/unit/i18n11 tests cover: at-least-4 locales beyond English (per family), per-file exact-key parity for each locale, every value is a non-empty string.
Limitations
- Webview content (the custom markdown editor's toolbar buttons,
table-export labels, mermaid controls) is currently English-only.
Plumbing the bundle into the webview means either (a) shipping the
bundle as JSON and resolving on the renderer side, or (b) sending the
resolved strings via the existing
updatepostMessage. Either is a natural follow-up. - Slideshow preview (reveal.js client) and the published static site also remain English-only — they don't run in a VSCode locale context.
- Translations beyond English were drafted in a single pass and not reviewed by native speakers; PRs to refine es/fr/de/ar idiom are very welcome.