Styling
Style Markdown output with renderer config, Tailwind Typography, directive themes, and stable hooks.
Styling
The renderer ships with practical defaults and supports customization through three separate surfaces:
configfor Markdown wrapper and typography presentationthemesfor named directive themescodefor code fence rendering behavior
Tailwind Typography
For best defaults, enable Tailwind Typography and scan the package output:
1pnpm add @tailwindcss/typography
1@import "tailwindcss";2@plugin "@tailwindcss/typography";3 4@source "../node_modules/@valkyrianlabs/payload-markdown/dist";
If you define custom directive themes with Tailwind classes, keep those class strings in source/config so Tailwind can scan them.
Renderer Config
1payloadMarkdown({2 config: {3 className: '[&_li::marker]:text-cyan-200/90',4 enableGutter: true,5 mutedHeadings: true,6 size: 'lg',7 variant: 'blog',8 wrapperClassName: 'max-w-4xl',9 },10})
config controls the Markdown wrapper and typography preset. It is not the directive theme registry and it is not code block configuration.
Variants And Sizes
Variants:
blog: larger article-style headings and prosedocs: denser documentation typographycompact: smaller vertical rhythm for panels and previewsunstyled: omits the plugin typography classes and uses yourclassName
Sizes:
lgmdsm
Directive Themes
Use themes for directive styling:
1payloadMarkdown({2 themes: {3 card: {4 items: [5 {6 name: 'forge',7 classes: 'rounded-2xl border border-cyan-400/40 bg-cyan-950/30 p-5',8 },9 ],10 },11 },12})
Then authors select the theme in Markdown:
1:::card[Custom Card]{theme="forge"}2Portable Markdown content.3:::
The renderer emits stable hooks such as:
data-directive="card"data-theme="forge"vl-md-cardvl-md-card--theme-forge
Deprecated Class Aliases
These still work but should not be the preferred customization path:
sectionClassNamecolumnClassName
Prefer directive themes:
1payloadMarkdown({2 themes: {3 columns: {4 items: [5 {6 name: 'panel',7 classes: 'grid grid-cols-1 gap-8 rounded-2xl border border-border/60 p-4',8 },9 ],10 },11 section: {12 items: [13 {14 name: 'panel',15 classes: 'my-12 rounded-2xl border border-border bg-card/70 p-6 shadow-sm',16 },17 ],18 },19 },20})
Legacy aliases remain available for older projects:
1payloadMarkdown({2 config: {3 columnClassName: 'gap-8 md:gap-12',4 sectionClassName: 'rounded-2xl border border-white/10 bg-white/5 p-6',5 },6})
Override Order
1plugin -> collection -> field/block scope -> direct renderer props
Later layers win for scalar config values. Class name values are joined.
