Directives Registry
The parsing primitive that maps :::name directive syntax to JSX components.
Core feature — always active, no configuration required.
What it does
The Directives Registry is the underlying primitive that enables the :::name (and ::name / :name) directive syntax in markdown. During compilation it translates directive syntax into JSX component calls, making it possible for both built-in features and custom project components to respond to directive blocks.
Without this registry, none of the directive-based features — including admonitions — would parse.
Directive shapes
Three shapes are supported:
| Shape | Syntax | Use case |
|---|---|---|
| Container | :::name[label]{attrs} … ::: | Multi-paragraph blocks (admonitions, code groups) |
| Leaf | ::name[label]{attrs} | Self-closing elements |
| Text (inline) | :name[label]{attrs} | Inline components |
Admonitions
The most common use of the registry is the admonition directives. This project registers the admonition vocabulary via the directives map (the recipe), so the following container directives are available:
Note
This is a :::note admonition.
Tip
Use :::tip for helpful suggestions.
Info
Use :::info for supplemental information.
Warning
Use :::warning for cautions that need attention.
Danger
Use :::danger for critical warnings.
Caution
Use :::caution for risky steps that need extra care.
Click to expand
Use :::details[label] for collapsible content.
Syntax
:::note[Optional title]
Content goes here.
:::The label in brackets is optional. Without a label the admonition renders with its default type name as the title.
Emitted markup
A :::note directive renders as:
<div data-admonition="note" class="admonition admonition-note">
<p class="admonition-title">Note</p>
<div class="admonition-body">…</div>
</div>The data-admonition attribute carries the variant name. The type-specific class (admonition-note, admonition-tip, etc.) is used for styling.
Custom directives
Registering a custom directive requires two steps: mapping the directive name in zfb.config.ts, and providing the component implementation in pages/.
Step 1 — Add the directive name → component name mapping in zfb.config.ts:
export default defineConfig({
markdown: {
features: {
directives: {
// existing entries...
callout: "Callout", // :::callout → <Callout>
},
},
},
});The value ("Callout") is the JSX tag name zfb emits in the compiled MDX output. It must match the key you register in the components map.
Step 2 — Bind the component name to its implementation in pages/:
import { Callout } from "@/components/content/callout";
export function createMdxComponents(lang) {
return {
// existing entries...
Callout,
};
}When an author writes :::callout, zfb emits <Callout> in the compiled MDX. The <entry. call resolves Callout to your component via this map. No Rust code is needed.
Notes
The admonition directives (
note,tip,info,warning,danger,caution,details) are provided by the admonitions recipe this project registers via thedirectivesmap — not by the Core registry itself. The registry is the engine; thedirectivesmap inzfb.config.tssupplies the directive-name → component-name bindings, andpages/supplies the component-name → implementation bindings._ mdx- components. ts Do not use
> [!IMPORTANT]or> [!CAUTION]GitHub-alert syntax unless you have verified thatimportantandcautioncomponents are registered. These map todata-admonition="important"/data-admonition="caution"respectively and will 500 if no component handles them.