The docmd 0.7.0 release is a major step forward — introducing native multi-language support (i18n) with a built-in translation system and true zero-config defaults where all core plugins are active out-of-the-box.

✨ Highlights

🌍 Internationalisation (i18n)

docmd now has first-class i18n support. Configure multiple locales and docmd builds a complete, localised version of your site for every locale — with locale-first URLs (/hi/, /zh/), translated UI strings, and automatic language detection.

Every locale lives in its own subdirectory — including the default language. This keeps your source directory clean and makes the structure easy to understand at a glance:

docs/
  en/default locale (renders at /)
  hi/Hindi (renders at /hi/)
  zh/Chinese (renders at /zh/)

The locale IDs, folder names, and default language are entirely your choice — en, hi, fr, de, or any identifier you prefer.

// docmd.config.js
export default {
  i18n: {
    default: 'en',
    locales: [
      { id: 'en', label: 'English' },
      { id: 'hi', label: 'हिन्दी' },
      { id: 'zh', label: '中文' },
    ]
  }
}

This includes Per-Locale Search Indexes spanning across your versions automatically, along with translated UI components for official plugins like Search and Threads!

🚀 Zero-Config Core Plugins

In 0.7.0, docmd embraces a true zero-config philosophy. All official core plugins (search, seo, sitemap, pwa, analytics, llms, mermaid) are now auto-included by default. You no longer need to declare them manually in your plugins array to use them.

If you want to disable a core plugin, you can now simply mark it as false:

export default {
  plugins: {
    search: false // Disables the automatically included search plugin
  }
}

📝 Complete Changelog

🌍 i18n Architecture

  • Clean locale directories: Every locale (including the default) lives in its own subdirectory inside src. No more mixing locale folders alongside content folders.
  • Locale-first URL generation: Build loop now builds nested directories for each configured locale.
  • Per-file fallback: Non-default locales inherit pages from the default locale when a translation is missing, with an automatic warning callout.
  • Per-locale navigation: Each locale directory can have its own navigation.json, falling back to the default locale’s navigation when absent.
  • Versioning + i18n: Old versions without locale directories are rendered in the default locale only. Add a locale subdirectory to any old version to enable translations for it.
  • Translated UI strings: Native translation system across all UI elements and templates. Handlers resolved against JSON locale files (en.json, hi.json, zh.json) — all template strings accessible via a fast t('key') helper.
  • Plugin i18n API: Plugins now support a new translations(localeId) hook alongside an i18n/ directory convention for client-side strings.
  • Global Search Locales: The local MiniSearch index is now built per-locale, dynamically rendering version badges based on context, and gracefully providing localised search results.
  • Zero-footprint fallback: Sites with no i18n block build identically to pre-0.7.0 — no path or output changes overhead.
  • String Mode (stringMode: true): A new i18n mode for noStyle pages — generate locale-specific HTML from a single source file. Add data-i18n attributes to your HTML, place translation files in assets/i18n/{locale}.json, and docmd clones the rendered output with server-side string replacement at build time. Produces fully translated, SEO-indexable pages at /{locale}/ paths. Supports data-i18n (textContent), data-i18n-html (innerHTML), and data-i18n-{attr} (attribute values). Missing translation files gracefully fall back to the default language. Designed for noStyle/HTML pages only — markdown documentation should use directory mode.
  • Client-side i18n for noStyle pages: A lightweight docmd-i18n-strings.js module is auto-injected when i18n is configured. Provides a runtime switchLocale() API, inPlace mode for SPAs, and a docmd:i18n-applied event for custom language switchers.

🔌 Plugin System & Engine

  • Core plugins auto-activation: Zero-config defaults automatically provide the complete docmd suite without config overhead.
  • Asset generation optimizations: Restructured asset pipeline so that static CSS, JS, and global configurations are built exactly once to the root, regardless of how many locales or versions are active.

🎨 UI & Containers

  • Container icon: parameter: Callouts, cards, collapsible sections, and buttons now accept an icon: parameter to render a Lucide icon inline with the title. Icons are vertically centred and properly sized using flexbox alignment.
    ::: card "Setup" icon:rocket
    ::: button "Get Started" /start icon:arrow-right
    
  • titleAppend frontmatter option: Pages can now set titleAppend: false in frontmatter to suppress the automatic — Site Title suffix in the <title> tag. Useful for homepages and landing pages.
  • Pill-style version & language switchers: The version dropdown and language switcher in the sidebar now render as compact pill buttons that sit side-by-side on the same line, saving vertical space. Shared CSS classes ensure consistent sizing across both components.
  • Language switcher version awareness: When browsing an old version that has no translations, non-default locales are visually disabled in the language switcher with an “N/A” badge, preventing broken navigation to non-existent pages.
  • Translatable “(Latest)” badge: The current version now displays an auto-generated, translatable “Latest” badge in the version dropdown. No longer hardcoded in the config label — uses the built-in translation system.
  • Search result version badges: Search results now display version badges as color-coded pills aligned to the right of the result title. Each version gets a deterministic color generated at build time for easy visual identification.
  • Responsive language pill: When both version and language pills are present, the language label auto-hides on standard sidebars and only shows the globe icon, expanding to show the label on wider screens.
  • Dev server config hot-reload: Changes to docmd.config.js now trigger a full rebuild during docmd dev without requiring a manual restart. File watcher correctly detects config file changes on all platforms.

🐛 Bug Fixes

  • Versioning + i18n conflict: Old version directories without locale subdirectories were being duplicated across all locales. Now correctly rendered for the default locale only — non-default locales skip versions that have no translations.
  • Ghost locale pages in old versions: Locale subdirectories inside old version directories (e.g. docs-v1/hi/) were rendered as regular content pages during the default locale pass, producing duplicate URLs. Fixed by filtering known locale directory names during the scan.
  • Navigation warning false positive: The “No navigation settings found” message was shown even when navigation.json existed inside locale or version directories. Now silent when navigation is available in any locale or version directory.
  • Auto-nav scanning wrong directory: When i18n is enabled, the auto-navigation builder was scanning the source root (which only contains locale directories), generating incorrect navigation from folder names. Now scans the default locale’s directory instead.
  • <title> tag missing site name: Pages without an explicit title produced empty title tags. The template now auto-appends the site title with an em-dash separator (Page — Site), and the homepage shows just the site title.
  • Language switcher URL duplication on old versions: Switching language while browsing a non-current version produced URLs with the version prefix duplicated (e.g. /zh/06/06/page). Fixed by stripping the version prefix from the page path before rebuilding the locale URL.

🧪 Quality Assurance

The 0.7.0 release passes a comprehensive brute test suite covering 25 distinct scenarios with 85 individual assertions — all green. Every major feature is tested both in isolation and in combination:

View full test coverage
# Scenario Assertions
1 Zero-config (no config file) 5
2 Zero-config with nested directories 4
3 i18n standalone (non-English default) 5
4 Versioning standalone (no i18n) 5
5 i18n + versioning combined 6
6 Old version with partial translations 4
7 Missing locale dir (graceful skip) 3
8 Navigation resolution priority 2
9 Frontmatter parsing 3
10 Containers (callout, tabs, steps, hero) 5
11 Code blocks (JS, Python) 3
12 Custom CSS/JS injection 3
13 Edit links 3
14 No-style pages 3
15 Search index generation 3
16 Sitemap generation 3
17 EJS content pages 3
18 README.md as index fallback 4
19 .markdown file extension 3
20 Deep nested structure (4+ levels) 2
21 Zero-config auto-nav accuracy 3
22 Title tag auto-append 2
23 Open Graph meta tags 3
24 Redirects 3
25 Per-page layout override 3

All 13 internal failsafe checks also pass. The brute test script is included in scripts/brute-test.js for anyone to run locally.

⚠️ Breaking Changes

  • Third-party plugin shorthand names are no longer resolved — you must use the full package name if you are importing third-party plugins. (search, threads, etc., are reserved strictly for @docmd/plugin-*).
  • pnpm onboard removed — the onboard script has been merged into pnpm prep. Use pnpm prep for full environment setup and pnpm prep --link (or pnpm verify --link) to also link docmd globally.
  • PWA Plugin is now an optional plugin and no longer auto-included, if you want to add PWA to your docs, use docmd add pwa command.

Migration Guide

Upgrade by running npm install docmd@latest. Then:

  1. You may remove core plugins from your plugins array if you were using them with default settings — they are now automatically enabled!
  2. If you use third-party plugins by shorthand, update them to their full package name.

See Getting Started — Installation for a full walkthrough.