For plugin authors. If you just want to call docmd from a Node script, see Build API instead. This page covers the lower-level utilities exposed by @docmd/api for writing plugins.
The @docmd/api package is the dedicated home for the plugin system. It provides hook registration, WebSocket RPC dispatch, source editing tools, and centralised URL utilities.
npm install @docmd/api
Note: All exports from @docmd/api are also available from @docmd/core. New projects should import directly from @docmd/api.
URL Utilities
Plugins should use these centralised utilities instead of rolling their own URL logic.
outputPathToSlug(outputPath)
Convert a build engine output path to a clean directory-style slug.
import { outputPathToSlug } from '@docmd/api';
outputPathToSlug('guide/index.html'); // → 'guide/'
outputPathToSlug('index.html'); // → '/'
outputPathToSlug('de/v1/api/index.html'); // → 'de/v1/api/'
outputPathToPathname(outputPath)
Convert to a root-relative pathname.
import { outputPathToPathname } from '@docmd/api';
outputPathToPathname('guide/index.html'); // → '/guide/'
outputPathToPathname('index.html'); // → '/'
outputPathToCanonical(outputPath, siteUrl)
Build a full canonical URL.
import { outputPathToCanonical } from "@docmd/api";
outputPathToCanonical("guide/index.html", "https://docs.example.com");
sanitizeUrl(url)
Collapse double slashes (except after protocol).
import { sanitizeUrl } from "@docmd/api";
sanitizeUrl("https://docs.example.com//guide"); // → "https://docs.example.com/guide"
sanitizeUrl("/foo//bar"); // → "/foo/bar"
buildAbsoluteUrl(base, localePrefix, versionPrefix, pagePath)
Build an absolute URL with locale and version prefixes.
import { buildAbsoluteUrl } from '@docmd/api';
buildAbsoluteUrl('/', 'de/', 'v1/', 'guide/'); // → '/de/v1/guide/'
resolveHref(href)
Normalise user-written hrefs to clean URLs. Handles .md stripping, trailing slashes, external: and raw: prefixes.
import { resolveHref } from "@docmd/api";
resolveHref("overview.md"); // → "overview/"
resolveHref("external:https://github.com"); // → "https://github.com"
resolveHref("raw:docs/readme.md"); // → "docs/readme.md"
Pre-computed Page URLs
Every page object includes pre-computed URL data. Plugins can read these directly with zero computation needed.
export async function onPostBuild({ pages, config }) {
for (const page of pages) {
console.log(page.urls.slug);
console.log(page.urls.canonical);
console.log(page.urls.pathname);
}
}
| Property | Type | Description |
|---|---|---|
slug |
string |
Clean directory-style slug (e.g., guide/ or /) |
canonical |
string |
Full canonical URL (only if config.url is set) |
pathname |
string |
Root-relative path (e.g., /guide/) |
Action & Event Dispatch
createActionDispatcher(hooks, options)
Creates a dispatcher that routes WebSocket RPC messages to plugin action/event handlers.
import { createActionDispatcher } from "@docmd/api";
const dispatcher = createActionDispatcher(
{ "actions": myPlugin.actions, "events": myPlugin.events },
{ "projectRoot": "/path/to/project", config, broadcast }
);
const { result, reload } = await dispatcher.handleCall("my-action", payload);
createSourceTools({ projectRoot })
Creates source editing utilities for markdown file manipulation.
import { createSourceTools } from "@docmd/api";
const source = createSourceTools({ "projectRoot": "/path/to/project" });
const block = await source.getBlockAt("docs/page.md", [10, 12]);
await source.wrapText("docs/page.md", [10, 12], "important", 0, "**", "**");
loadPlugins(config, options)
Loads, validates, and registers all plugins declared in the config. Returns the populated hooks registry.
import { loadPlugins, hooks } from "@docmd/api";
const registeredHooks = await loadPlugins(config, {
"resolvePaths": [__dirname]
});
Engine Loader API
The pluggable engine architecture allows programmatic resolution and instantiation of acceleration layers directly via @docmd/api.
loadEngine(engineName)
Resolves and initialises the requested build engine backend. If native architecture binaries are unavailable, it gracefully falls back to the high-performance JavaScript engine.
import { loadEngine } from "@docmd/api";
const engine = await loadEngine("rust");
const gitLogResult = await engine.runWorkerTask("git:log", { "paths": ["docs/guide.md"] });
registerEngine(engineName, engineInstance)
Allows custom tools or third-party integrators to register custom execution engines programmatically.
import { registerEngine } from "@docmd/api";
registerEngine("custom", myCustomEngineImpl);
Type Exports
For TypeScript plugin authors, the following types are available:
import type {
PluginModule,
PluginDescriptor,
PluginHooks,
PageContext,
BeforeBuildContext,
PostBuildContext,
Capability,
ActionContext,
ActionHandler,
EventHandler,
SourceTools,
BlockInfo,
TextLocation,
Engine,
} from '@docmd/api';
What’s Next
- Building Plugins — start here.
- Plugin Examples — see a full plugin walkthrough.
- Engines & Architecture — Rust engine, N-API, and engine loader internals.