Customizing Markdown
How zfb renders Markdown and how to configure or extend the pipeline.
zfb's Markdown pipeline lives in the zfb-content Rust crate. It parses
each file, runs a chain of visitors (Core always-on, plus any Opt-in
features you enable), highlights code blocks server-side with syntect,
and hands each entry back as both a raw body string and a
ready-to-render Content component.
For the full list of what the pipeline provides — Core features that are
always on, Opt-in features you enable in zfb.config.ts, and how to add
your own visitors in-tree — see the
Markdown Features category.
Rendering Markdown in a page
The standard pattern is to receive a content entry through paths() and
render its Content component:
import { getCollection } from "zfb/content";
export function paths() {
const posts = getCollection("blog");
return posts.map((post) => ({
params: { slug: post.slug },
props: { post },
}));
}
export default function PostPage({ post }) {
return (
<article className="prose">
<post.Content />
</article>
);
}entry.Content is the JSX component zfb compiles from your Markdown. It
renders MDX-aware output including syntect-highlighted code blocks and any
custom directives you have registered. If you only need the raw markdown
source (for example, to compute a summary or feed an RSS generator), reach
for entry.body instead.
Extension points
The plugins: [] field in zfb.config is the build-orchestration plugin
system. Each registered plugin exposes four optional hooks — setup,
preBuild, postBuild, and devMiddleware — for tasks like registering
import aliases and virtual modules at boot (setup), emitting extra files
alongside the build (preBuild), running post-build verification
(postBuild), or adding routes to the dev server (devMiddleware). Plugins
do not participate in Markdown rendering: the parse and visitor chain run
inside the Rust engine and never call back into npm-installed plugins.
Markdown-pipeline customisation lives in-tree as MdastVisitor /
HastVisitor implementations on the engine side. See
Extending the Markdown Pipeline.
Tip
When in doubt, render the body and style it. Most "I want to customize Markdown" requests turn out to be styling questions that CSS solves.
See also
Markdown Features — full catalog of Core and Opt-in features.
Custom Directives — register new directive names against the
DirectiveRegistry, no Rust required.Extending the Markdown Pipeline — write a Rust visitor and wire it into the engine.