Admonitions preset
Opt-inEnable the seven built-in admonition directive types (note, tip, warning, danger, info, details, caution) and register your own.
The admonitionsPreset feature registers the seven built-in admonition directive types: note, tip, warning, danger, info, details, and caution. It also accepts an object form to register project-specific directives and optionally suppress the defaults.
Enable
// zfb.config.ts
export default defineConfig({
markdown: {
features: {
admonitionsPreset: true,
},
},
});
Usage
Use the CommonMark Directives syntax with ::: fences, separating each fence from surrounding content with blank lines:
:::note[Optional title]
Note body text.
:::
:::tip
Tip body text.
:::
:::warning
Warning body text.
:::
All seven kinds: note, tip, warning, danger, info, details, caution.
The bracketed [label] is promoted to a title="…" attribute on the emitted JSX element:
<Note title="Optional title">Note body text.</Note>
The :::details kind also accepts the legacy unbraced form for title:
:::details title="Click me"
Hidden content.
:::
Blank-line requirement
Each fence line (:::note and the closing :::) must be separated from surrounding content by blank lines so the Markdown parser treats them as separate paragraphs. Without blank lines the content is not recognised as a directive and a warning diagnostic is emitted at build time.
Registering your own directives
Pass an options object instead of true to add project-specific :::name directives or replace built-ins.
Short form — bare component name
The simplest entry maps a directive name to a component identifier string. The directive is registered as a container with title_from_label: true (the [label] becomes a title="…" attribute).
// zfb.config.ts
export default defineConfig({
markdown: {
features: {
admonitionsPreset: {
extraDirectives: {
spoiler: "Spoiler",
},
},
},
},
});
:::spoiler in Markdown now emits <Spoiler>.
Object value form — full spec
Use an object value to control the directive shape (container, leaf, or text) and whether the bracketed label becomes a title attribute.
// zfb.config.ts
export default defineConfig({
markdown: {
features: {
admonitionsPreset: {
extraDirectives: {
kbd: {
component: "Kbd",
kind: "text",
titleFromLabel: false,
},
},
},
},
},
});
:kbd[Ctrl+C] in Markdown emits <Kbd>Ctrl+C</Kbd>.
Overriding a built-in
extraDirectives entries are registered after the standard seven, so a name collision replaces the built-in:
// zfb.config.ts
export default defineConfig({
markdown: {
features: {
admonitionsPreset: {
extraDirectives: {
caution: "MyCaution",
},
},
},
},
});
:::caution now emits <MyCaution> instead of <Caution>.
Suppressing the built-ins entirely
Set extendDefaults: false to skip the standard seven and register only what you declare:
// zfb.config.ts
export default defineConfig({
markdown: {
features: {
admonitionsPreset: {
extendDefaults: false,
extraDirectives: {
callout: "Callout",
aside: "Aside",
},
},
},
},
});
Only :::callout and :::aside are registered. None of the standard seven kinds work.
Important: registering a directive does not provide a component
zfb is framework-agnostic and ships no admonition React (or other) components. Registering a directive only tells the pipeline to emit <ComponentName> in compiled MDX. You must:
- Author the component yourself (e.g. in
_mdx-components.ts). - Add it to your project’s MDX components map.
- Style it with your own CSS.
Casing and verbatim emit
The value you supply ("Spoiler", "MyCaution", "Kbd") is the JSX component identifier emitted verbatim — there is no auto-PascalCasing and no validation. caution: "Caution" emits <Caution>; caution: "my-caution" emits <my-caution> (a DOM element, likely not what you want).
The directive-name key follows the directive grammar [A-Za-z_][A-Za-z0-9_-]*. A key that does not match this pattern will simply never match any :::name in source.
📝 Note
The object value form ({ component, kind, titleFromLabel }) is forward-compatible with a planned top-level generic directives feature that will unify all directive registrations in one place. No migration will be needed.
See also
- Directives registry — the underlying Core primitive.
- Custom Directives — register directives via the Rust pipeline API.