Valkyrian Labs logo

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:

  • config for Markdown wrapper and typography presentation
  • themes for named directive themes
  • code for 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 prose
  • docs: denser documentation typography
  • compact: smaller vertical rhythm for panels and previews
  • unstyled: omits the plugin typography classes and uses your className

Sizes:

  • lg
  • md
  • sm

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-card
  • vl-md-card--theme-forge

Deprecated Class Aliases

These still work but should not be the preferred customization path:

  • sectionClassName
  • columnClassName

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.