Plugin Config
Use the public Payload Markdown config model for fields, blocks, code rendering, themes, and presentation defaults.
Plugin Config
Full Example
1import { DEFAULT_CODE_LANGS, payloadMarkdown } from '@valkyrianlabs/payload-markdown'2 3payloadMarkdown({4 enabled: true,5 code: {6 enhanced: true,7 fullBleed: false,8 langs: [...DEFAULT_CODE_LANGS, 'latex', 'r'],9 lineNumbers: true,10 shikiTheme: 'github-dark',11 },12 icons: {13 baseDir: '../public/icons',14 packs: [15 { alias: 'fa-duotone', path: 'fa/duotone' },16 { alias: 'brand', path: 'brand' },17 ],18 },19 collections: {20 pages: true,21 posts: {22 fieldName: 'body',23 field: {24 label: 'Body Markdown',25 localized: true,26 required: true,27 },28 installField: true,29 installIntoBlocks: false,30 code: {31 lineNumbers: false,32 },33 config: {34 variant: 'docs',35 },36 themes: {37 card: {38 items: [39 {40 name: 'postHeroCard',41 classes: 'rounded-2xl border border-white/10 bg-cyan-950/30 p-5',42 },43 ],44 },45 },46 },47 },48 config: {49 size: 'lg',50 variant: 'blog',51 },52 themes: {53 card: {54 items: [55 {56 name: 'feature',57 classes: 'rounded-2xl border border-cyan-400/40 bg-cyan-950/30 p-5',58 },59 ],60 },61 },62})
Top-Level Options
enabled: set tofalseto return the incoming Payload config unchangedcollections: map of collection slugs totrue, an options object, or a falsey value to skipcode: Shiki and fenced code rendering defaultsicons: local SVG icon packs available to Markdown directivesthemes: directive theme registry extensionsconfig: Markdown wrapper and typography defaults
Runtime settings initialization
Runtime helpers read plugin settings from payloadMarkdown(...). If you use renderer helpers before the plugin initializes, getPayloadMarkdownSettings() throws. In normal Payload usage, include the plugin in the config before rendering Markdown.
Icons
Configure local SVG icon packs with icons:
1payloadMarkdown({2 icons: {3 baseDir: '../public/icons',4 packs: [5 { alias: 'fa-duotone', path: 'fa/duotone' },6 { alias: 'brand', path: 'brand' },7 ],8 },9})
Expected folder layout:
1public/icons/2 fa/duotone/3 home.svg4 rocket.svg5 brand/6 github.svg
Markdown references use @pack/name:
1::button[Home]{2 href="/home"3 icon="@fa-duotone/home"4}5 6::button[GitHub]{7 href="https://github.com/valkyrianlabs"8 icon="@brand/github"9 newTab=true10}
Only local SVG packs are supported. The plugin does not integrate FortAwesome packages, fetch remote icons, or accept arbitrary icon URLs.
Paid or pro icon files should stay local and gitignored. CI-safe tests and fixtures should use tiny committed SVG fixtures outside public/icons, and local paid-icon checks should be opt-in only.
The server renderer emits sanitized inline SVG in the rendered HTML. If your app needs a bundler-backed static import registry for SVG component workflows, use the advanced icon registry helper to generate static imports from your local pack layout. Those imports rely on your host app's SVG support, such as Next, SVGR, Webpack, Turbopack, or an equivalent loader. Keep generated files that import paid icons out of source control.
Collection Options
Collection entries can be true or an object:
1payloadMarkdown({2 collections: {3 posts: true,4 pages: {5 fieldName: 'content',6 installField: false,7 installIntoBlocks: true,8 },9 },10})
Collection object options:
fieldName: name for the auto-installed Markdown field, defaulting tocontentfield: field options passed tomarkdownField()exceptnameinstallField: explicitly add or skip a standalone Markdown fieldinstallIntoBlocks: explicitly add or skipMarkdownBlockinside collectionblocksfieldscode: collection-scoped code rendering overridesthemes: collection-scoped directive themesconfig: collection-scoped wrapper and typography config
Field Options
Auto-installed fields support:
admindefaultValuelabellocalizedrequired
1payloadMarkdown({2 collections: {3 posts: {4 fieldName: 'body',5 field: {6 admin: {7 description: 'Use Markdown and supported directives.',8 },9 defaultValue: '# Draft',10 label: 'Body Markdown',11 localized: true,12 required: true,13 },14 installField: true,15 },16 },17})
Config Namespace
config controls presentation around the rendered Markdown:
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})
Supported variants are blog, docs, compact, and unstyled. Supported sizes are lg, md, and sm.
Split Field And Block Config
config can also be split by scope:
1payloadMarkdown({2 config: {3 blocks: {4 size: 'md',5 variant: 'docs',6 },7 field: {8 size: 'lg',9 variant: 'blog',10 },11 },12})
Use the split shape when block layouts need denser typography while standalone fields use article-style typography.
Deprecated Aliases
These remain supported but are not preferred:
config.options.langstocode.langsconfig.options.lineNumberstocode.lineNumbersconfig.options.themetocode.shikiThemeconfig.options.enhancedCodeBlockstocode.enhancedconfig.fullBleedCodetocode.fullBleedconfig.sectionClassNameto directive themesconfig.columnClassNameto directive themes
New code values win over legacy aliases at the same scope.
