Vaulthalla Logo

Rendering

Render Markdown fields and blocks with server-first components and scoped configuration.

Rendering

Markdown rendering is server-friendly and centralized in the plugin renderer. The same pipeline handles Markdown, GFM, Shiki code blocks, heading anchors, sanitized HTML, and registry-backed directives.

Render A Markdown Field

1import { MarkdownRenderer } from '@valkyrianlabs/payload-markdown/server'2 3export function PostBody({ content }: { content?: string | null }) {4  return (5    <MarkdownRenderer6      collectionSlug="posts"7      markdown={content}8      scope="field"9    />10  )11}

Set collectionSlug when you want collection-scoped code, themes, or config to apply.

Renderer Props

Common props:

  • markdown: Markdown source string
  • collectionSlug: collection key used for config resolution
  • scope: field or blocks
  • variant: blog, docs, compact, or unstyled
  • size: lg, md, or sm
  • as: HTML tag for the rendered Markdown container, defaulting to article
  • className: class names for the Markdown element
  • wrapperClassName: class names for the outer wrapper
  • enableGutter: adds horizontal wrapper padding
  • mutedHeadings: slightly reduces heading contrast
  • emptyFallback: returned for empty or whitespace-only Markdown
  • errorFallback: returned when compilation produces warnings and you prefer a fallback
  • code: local Shiki and code fence overrides
  • themes: local directive theme overrides

Local Overrides

Direct component props are the final override layer:

1<MarkdownRenderer2  as="section"3  code={{4    fullBleed: true,5    lineNumbers: true,6  }}7  collectionSlug="posts"8  emptyFallback={<p>No content yet.</p>}9  markdown={post.content}10  scope="field"11  size="lg"12  themes={{13    card: {14      items: [15        {16          name: 'localFeature',17          classes: 'rounded-2xl border border-cyan-400/40 bg-cyan-950/30 p-5',18        },19      ],20    },21  }}22  variant="blog"23  wrapperClassName="max-w-4xl"24/>

Most applications should prefer plugin-level or collection-level config. Renderer-level overrides are useful for previews, one-off marketing pages, and admin-only rendering surfaces.

Render Blocks

1import { MarkdownBlockComponent } from '@valkyrianlabs/payload-markdown/server'2 3export function MarkdownLayoutBlock({4  block,5  collectionSlug,6}: {7  block: {8    blockType: 'vlMdBlock'9    content: string10  }11  collectionSlug?: string12}) {13  return <MarkdownBlockComponent {...block} collectionSlug={collectionSlug} />14}

MarkdownBlockComponent resolves block scoped defaults with resolveMarkdownBlockDefaults(collectionSlug) and passes scope="blocks" to MarkdownRenderer.

Sanitized HTML And GFM

The render pipeline uses remark-gfm, rehype-raw, and rehype-sanitize. Markdown tables, task lists, strikethrough, and raw HTML are parsed, but unsupported or unsafe HTML is sanitized. Authored inline style attributes are stripped before final output.

When warnings matter

compileMarkdown() returns warnings for malformed directives, invalid directive attributes, unknown themes, and renderer failures. MarkdownRenderer returns errorFallback when warnings exist and errorFallback is provided.