valkyrianlabs

payload markdown

by valkyrianlabs
Rich text & editors
v3
^3.0.0
MIT

Overview

Summary generated from the README

Adds Markdown fields and blocks to Payload collections, edited in a CodeMirror editor and rendered on the server with Shiki highlighting. Content stays portable Markdown, with directives for callouts, cards, buttons, tabs and column layouts, plus themes, icon packs and palettes. It can also plug into the official Payload MCP plugin so AI agents can read, validate and edit content as drafts. Styling works best with Tailwind Typography.

Features

  • Markdown field and block modes configurable globally or per collection
  • CodeMirror editor with directive autocomplete, syntax highlighting and diagnostics
  • Shiki-powered code blocks with configurable languages, themes and line numbers
  • Directives for callouts, details, TOC, steps, cards, buttons, tabs and column layouts
  • Named directive themes, local SVG icon packs and colour palettes
  • MCP integration with tools to read, validate, write and publish content as drafts

Use cases

  • Author documentation pages and technical blog posts in portable Markdown inside Payload
  • Build landing-page sections with cards and buttons without a page builder or rich text JSON
  • Let AI agents draft and edit site content over MCP while editors review drafts in the admin

From the author

Structured Markdown editing and rendering for Payload CMS with CodeMirror, Shiki, directives, themes, and server-first output.

Installation

npm i @valkyrianlabs/payload-markdown

8

Stars

0

Forks

1

Open Issues

2 days ago

Last Updated

0

Weekly Downloads

v1.8.1

npm Version

1.7 MB

Unpacked Size

39

Dependencies

GitHub stars

Trends appear after 7 days of data. Daily snapshots have not started yet.

npm weekly downloads

Trends appear after 7 days of data. Daily snapshots have not started yet.

Each point is npm's rolling 7-day download count.

Health Score

49/100Fair

Composite score based on GitHub activity, stars, npm downloads, publish recency, dependency count, and package size.

Badge for your README

Payload Directory health badge
Markdown
[![Payload Directory](https://payloaddirectory.dev/badge/1197676810-root.svg)](https://payloaddirectory.dev/plugins/1197676810-root)
HTML
<a href="https://payloaddirectory.dev/plugins/1197676810-root"><img src="https://payloaddirectory.dev/badge/1197676810-root.svg" alt="Payload Directory"></a>
Updated Oct 18, 2026Created Mar 31, 2026Published Oct 14, 2026

README

@valkyrianlabs/payload-markdown

GitHub Workflow Status   npm   npm   npm   license

Payload Markdown

Structured Markdown editing and rendering for Payload CMS.

payload-markdown gives Payload a Markdown-first authoring system with a CodeMirror editor, Shiki-powered code blocks, registry-backed directives, local SVG icon packs, buttons, cards, table-of-contents generation, autocomplete, diagnostics, and server-first rendering.

No bloated rich text editor.
No JSON-shaped content prison.
No MDX ceremony for common docs/blog layouts.

Just portable Markdown that renders like a real system.

Payload Markdown now feels much closer to a Markdown-native design system: readable [Title] directive labels, expanded multiline args, local icon packs, button primitives, smarter autocomplete, richer card linking, and editor readability aids without giving up portable Markdown.

New in v1.7: AI agents can manage your content. Connect Claude, Cursor, or any MCP client to your Payload app and ask for changes in plain language.


Install

pnpm add payload-markdown

[!IMPORTANT] Install the agent skill. If you use Payload MCP or let AI agents (Claude Code, Codex) work in your repo, install the skill that ships with the package so they know every directive, theme and the MCP workflow:

npx payload-markdown skill install

Run it again after upgrading. npx payload-markdown skill check fails when the installed skill has drifted from the package, and agents are told to suggest the update when they notice.

payload-markdown is also published as @valkyrianlabs/payload-markdown: the same package, built once and released at the same version, and still fully supported. Import from whichever name you installed (@valkyrianlabs/payload-markdown/server instead of payload-markdown/server, and so on), and install only one of them.


🤖 Let AI agents manage your content

"Rewrite the Home page from our launch post. Use cards for the features and add an FAQ after the hero."

Say that to Claude, Cursor, or any MCP client, and it gets done. The agent finds the page, writes payload-markdown using the directives, themes, icons, and code languages your site actually has, validates every block with your renderer, and saves a draft for you to review in the admin.

payload-markdown/mcp plugs into Payload's official @payloadcms/plugin-mcp:

import { mcpPlugin } from '@payloadcms/plugin-mcp'
import { payloadMarkdown } from 'payload-markdown'
import { withPayloadMarkdownMcp } from 'payload-markdown/mcp'

export default buildConfig({
  plugins: [
    payloadMarkdown({ collections: { pages: true, posts: true } }),
    mcpPlugin(
      withPayloadMarkdownMcp({
        collections: { pages: { enabled: true }, posts: { enabled: true } },
      }),
    ),
  ],
})

Create an API key in the admin (MCP → API Keys), then connect your agent:

claude mcp add --transport http payload http://localhost:3000/api/mcp \
  --header "Authorization: Bearer <key>"
ToolWhat the agent gets
markdownGuideA site-aware authoring guide, generated live from your config: where markdown lives, your themes, icons, and code languages, every directive and attribute.
markdownReadFind documents by id, title, slug, or query and see every markdown field and block with stable refs.
markdownValidateRender-exact validation with line and column diagnostics.
markdownWriteAtomic replace, insert, and remove edits. Validated first, saved as a draft, other blocks untouched.
markdownPublishPublish the draft, only when you ask.

Built to be trusted with a real site:

  • Drafts by default. Nothing goes live until you, or an agent you told to, publishes.
  • Validation gate. Broken directives, unknown themes, and missing icons are caught before anything is saved.
  • Surgical, atomic edits. Blocks are addressed by id, and only the fields that changed are written.
  • Conflict-safe. ifUpdatedAt refuses stale writes, and open (locked) documents are respected.
  • Least privilege. Every call runs as the key's user under your Payload access control, plus the key's per-collection checkboxes.

The package also ships an agent skill so Claude Code and Codex know the workflow out of the box: npx payload-markdown skill install (see Install).

AI Agents and MCP guide →


📖 Explore the Docs

Full setup, directive syntax, theme configuration, code block options, editor behavior, and migration notes live in the docs.


Why this exists

Most CMS content systems eventually force you into one of two weak paths:

  • heavy rich text editors with fragile JSON-shaped content
  • bare Markdown fields with no structure, no layout, and no serious authoring support

This plugin takes the third path:

  • Markdown stays the source of truth
  • structure lives directly in the content
  • rendering is production-ready by default
  • directives provide layout, buttons, cards, and common calls to action without turning content into a page-builder blob
  • themes provide clean visual control without runtime Tailwind roulette
  • autocomplete, syntax highlighting, closing labels, and diagnostics make authoring fast instead of fussy

Write fast. Render clean. Stay in control.


What you get

  • Drop-in fields — Markdown fields for Payload collections
  • Markdown blocks — block support for Payload layouts
  • Editor UX — CodeMirror-powered editing
  • Code rendering — Shiki-powered highlighting
  • Server-first output — clean rendering without client ceremony
  • Structured directives — callouts, details, TOCs, steps, cards, buttons, tabs, and layouts
  • Buttons — ::button leaf directives and :::buttons groups
  • Icon packs — local SVG packs referenced as @pack/name
  • Autocomplete — directive snippets, placeholders, and editor-only snippet variants
  • Diagnostics — lightweight authoring warnings
  • Heading anchors — automatic IDs and table-of-contents support
  • Themes — themeable directive output with stable hooks
  • Card links — linkScope and newTab controls for card and cards layouts
  • Scoped config — global and collection-level overrides
  • Portable storage — clean Markdown source
  • AI agents over MCP — agents read, edit, validate, and publish content with drafts and API key permissions
  • AI-friendly workflow — content that agents and humans can edit sanely

Payload Markdown directive preview

payload-markdown renders structured Markdown directly inside the Payload admin preview, including callouts, details, TOCs, steps, cards, buttons, tabs, themes, icons, and code blocks — without turning your content into JSON-shaped sludge.


v1.4 authoring primitives

New examples prefer labels for visible titles and expanded attrs for anything non-trivial:

:::card[Fast Setup]{
  href="/getting-started/installation"
  linkScope="title"
  icon="@fa-duotone/bolt"
}
Install, configure, ship.

:::buttons{
  align="center"
  stack="mobile"
  gap="md"
}
::button[Read Docs]{
  href="/docs"
  variant="primary"
  icon="@fa-duotone/book-open"
}

::button[GitHub]{
  href="https://github.com/valkyrianlabs/payload-markdown"
  variant="secondary"
  icon="@brand/github"
  newTab=true
}
:::

:::

The older title="" form remains compatible, but [Title] keeps visible content out of the argument list. Card and cards directives support scoped linking through linkScope; use linkScope="title" when a card body contains buttons or links.

Editor completion can expose shortcuts such as ::button, ::button_icon, and ::button_full, but generated Markdown always uses the canonical ::button directive. Syntax highlighting now distinguishes directive names, labels, arg names, arg values, and leaf-vs-container directives, while closing labels make nested ::: blocks easier to scan.


Directive system

Payload Markdown supports structured directives for real content layouts:

  • :::callout
  • :::details
  • :::toc
  • :::steps
  • :::cards
  • :::card
  • ::button
  • :::buttons
  • :::tabs
  • :::tab
  • :::section
  • :::2col
  • :::3col
  • :::cell

Directives are plain Markdown. They stay readable in Git, easy to review in PRs, and simple for AI/editor tooling to maintain.

See the docs for directive syntax, supported attributes, nesting behavior, themes, and examples:

Directive documentation →


Themes

Directive themes are first-class.

Themes live beside config, not inside it. Theme objects use classes, not className.

Default themes are included automatically. You only define custom themes when you want to extend or override the built-ins.

Themes can be configured globally or scoped per collection, then selected directly from Markdown using directive attributes.

Stable classes and data attributes are emitted for overrides, including data-directive, data-theme, and vl-md-* hook classes.

Theme documentation →


Colour palettes

Palettes are named colour themes that colour individual icons and recolour directives, on top of their structural theme:

:::card[Linux]{icon="@fa-brands/debian palette=debian, @fa-brands/ubuntu palette=ubuntu" theme="glass"}
Debian and Ubuntu support.
:::

Each icon carries its own palette, so order never swaps colours. Palettes paint the SVG itself (brand icons, duotone layers, explicit fills), follow light and dark mode, and come built in for every Tailwind hue. Define more in code, or enable appearance: true to manage them in the admin and over MCP at runtime, without CSS or a rebuild.

Palette documentation →


Code config

Code block rendering has its own top-level code namespace.

Use it to configure Shiki languages, the Shiki theme, line numbers, enhanced rendering, and full-bleed code behavior.

Legacy config.options still works, but code is the preferred API.

Migration mapping:

  • config.options.langs → code.langs
  • config.options.lineNumbers → code.lineNumbers
  • config.options.theme → code.shikiTheme
  • config.options.enhancedCodeBlocks → code.enhanced
  • config.fullBleedCode → code.fullBleed

Code block documentation →


Quick setup

Register the plugin in your Payload config, enable it for one or more collections, then render Markdown content with the server renderer.

The full setup guide covers:

  • plugin registration
  • collection configuration
  • field mode
  • block mode
  • server rendering
  • scoped config
  • themes
  • code block options

Quick start →


Editor experience

The editor is built on CodeMirror and includes:

  • Markdown syntax highlighting
  • directive autocomplete, including snippet variants such as ::button_icon
  • directive snippets with canonical Markdown output
  • snippet placeholders/tabstops
  • theme-aware attribute suggestions
  • highlighting for directive labels and expanded arg blocks
  • visual closing labels for nested directive blocks
  • lightweight diagnostics for malformed directives
  • warnings for unknown directives, invalid variants, invalid themes, malformed attrs, and common structural issues

The goal is simple: author Markdown like text, but get enough tooling that complex docs stay pleasant.

Editor documentation →


Tailwind setup

For best rendering defaults, enable Tailwind Typography and scan the plugin output.

Required pieces:

  • install @tailwindcss/typography
  • enable the typography plugin
  • add the plugin dist directory to Tailwind sources
  • if your site switches between light and dark with a class or attribute, declare it with @custom-variant dark so the Markdown output follows it

Theme class strings defined in your app config should also live in scanned source files.

Runtime arbitrary Tailwind classes inside CMS-authored Markdown are not the recommended styling path. Use directive theme="..." values and configure named themes in source.

Tailwind setup →


Built for docs, blogs, and technical content

Use one Markdown field to author:

  • release notes
  • documentation pages
  • technical blog posts
  • plugin docs
  • install guides
  • API walkthroughs
  • landing-page sections

The content stays readable in Git and editable in Payload.


Philosophy

  • Markdown should stay the source of truth
  • content should remain portable
  • structure should be readable in plain text
  • rich layouts should not require a page builder
  • defaults should look good without locking you in
  • styling should be centralized, themeable, and overridable
  • the renderer should respect its container
  • AI and human editors should both be able to work with the content

If that aligns with how you build, this will feel right.

Similar plugins