Plugin Config
Configure payloadMarkdownDocs for the dedicated docs workflow.
Plugin Config
payloadMarkdownDocs() is a Payload plugin factory.
1import { payloadMarkdownDocs } from '@valkyrianlabs/payload-markdown-docs'2 3payloadMarkdownDocs({4 enabled: true,5})
An enabled plugin injects the default docs infrastructure and registers the sync endpoint. A disabled plugin is an exact no-op.
Recommended Config
1import { payloadMarkdownDocs } from '@valkyrianlabs/payload-markdown-docs'2import { buildConfig } from 'payload'3 4export default buildConfig({5 plugins: [6 payloadMarkdownDocs({7 auth: {8 githubOidc: true,9 },10 target: {11 type: 'docsCollection',12 enableDrafts: true,13 },14 sync: {15 allowWrites: true,16 allowPublish: true,17 allowHardDelete: false,18 deleteBehavior: 'archive',19 },20 }),21 ],22})
Main Sections
authenables sync request verification modes. UsegithubOidc,ed25519, or both on the same endpoint.targetconfigures the dedicated generated docs collection.synccontrols write, publish, and delete authority.routingconfigures route collision checks.collectionscustomizes infrastructure collection slugs.
GitHub trust belongs in Docs Globals > Trusted. Ed25519 public keys belong in
Docs Globals > Keys. Docs packages belong in Docs Globals > Sets.
See sync config and routing config for the safety gates.
Real App Pattern
Most apps keep the plugin config small and move package-specific decisions to Payload Admin:
- register the plugin once in
payload.config.ts - create one docs set per docs package in
Docs Globals > Sets - use docs groups for route namespaces such as
/plugins - add global GitHub owners in
Docs Globals > Trusted - add Ed25519 public keys in
Docs Globals > Keysonly for local or non-GitHub CI - render docs from a Next route with the
/nextadapter - serve raw
.mdexports from explicit Next route handlers
Do not add one Payload Page per Markdown file. The generated docs collection is
internal storage for synced content, route resolution, search, and admin review.
Minimal Local Config
For local validation or admin-only experiments, this is enough to register the collections and sync endpoint:
1payloadMarkdownDocs({2 enabled: true,3})
That does not make sync writes publicly usable. Authentication is disabled until
you enable auth.githubOidc, auth.ed25519, or both. Sync writes are rejected
until sync.allowWrites: true.
Auth Patterns
GitHub Actions publishing usually uses OIDC:
1payloadMarkdownDocs({2 auth: {3 githubOidc: true,4 },5})
Local machines and non-GitHub CI can use Ed25519 request signatures:
1payloadMarkdownDocs({2 auth: {3 ed25519: true,4 },5})
Both modes can be enabled on the same endpoint. A bearer token is treated as a GitHub OIDC request; Ed25519 headers are treated as a signed request.
Target Collection
The implemented target is the dedicated generated docs collection:
1payloadMarkdownDocs({2 target: {3 type: 'docsCollection',4 enableDrafts: true,5 markdownField: 'content',6 },7})
target.type currently only accepts docsCollection. Existing collection and
block targets are intentionally not implemented.
target.markdownField renames the generated Markdown field. If you customize it,
pass the same field name to the /next helpers:
1await resolvePayloadMarkdownDocsRoute({2 payload,3 slug,4 markdownField: 'body',5})
Collection Slugs
Infrastructure collection slugs can be customized when an app already reserves the defaults:
1payloadMarkdownDocs({2 collections: {3 docs: { slug: 'generated-docs' },4 docsGroups: { slug: 'docs-groups' },5 docsSets: { slug: 'docs-sets' },6 docsKeys: { slug: 'docs-keys' },7 docsTrusted: { slug: 'docs-trusted' },8 syncRuns: { slug: 'docs-sync-runs' },9 nonces: { slug: 'docs-sync-nonces' },10 },11})
The plugin rejects duplicate requested slugs and slugs that already exist in the
incoming Payload config. If both target.slug and collections.docs.slug are
provided, they must match.
Disabling infrastructure collections is an advanced integration path. Normal apps should leave the defaults enabled; the sync endpoint needs docs sets for source resolution and needs audit/nonces for applied sync.
Hero Images
Generated docs records include an optional heroImage upload field. It uses the
media collection by default.
Add extra upload collections when your app stores docs imagery elsewhere:
1payloadMarkdownDocs({2 target: {3 heroImage: {4 additionalMediaCollections: ['docs-media'],5 },6 },7})
Set target.heroImage: false to omit the field.
Endpoint
The sync endpoint defaults to /api/payload-markdown-docs/sync because Payload
mounts plugin endpoints under /api.
1payloadMarkdownDocs({2 endpoint: {3 path: '/payload-markdown-docs/sync',4 maxBodyBytes: 5_000_000,5 },6})
Set enabled: false only for environments where the plugin should be a complete
no-op.
