5.2 KiB
| title | aliases | tags | sources | created | updated | |||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Versions — Drafts |
|
|
|
2026-05-15 | 2026-05-15 |
Overview
Drafts build on wiki/payloadcms/versions-autosave to let you save changes without publishing them immediately. Requires versions to be enabled first.
// Collection or Global
versions: {
drafts: {
autosave: true, // or pass autosave options object
schedulePublish: true, // allow future publish/unpublish events
validate: false, // validate on draft save (default: false)
localizeStatus: false, // Beta: localize _status field
},
}
Database Changes
Enabling drafts injects a _status field ('draft' | 'published') into your schema automatically.
Admin UI statuses:
- Draft — never published; only draft versions exist
- Published — published, no newer drafts
- Changed — published, but newer unpublished drafts exist
How draft Param and _status Work Together
| Operation | draft param |
_status in data |
Result |
|---|---|---|---|
| Create | true or false |
omitted | Main collection updated with _status: 'draft' |
| Create | true or false |
'published' |
Main collection updated with _status: 'published' |
| Update | true |
omitted or 'draft' |
Only versions table updated; main collection unchanged |
| Update | true |
'published' |
Main collection updated with _status: 'published' (override) |
| Update | false or omitted |
omitted | Main collection updated with _status: 'draft' |
| Update | false or omitted |
'published' |
Main collection updated with _status: 'published' |
Key distinctions:
draft: true→ skips required field validation + writes only to versions table_status: 'published'→ overridesdraft: trueand updates the main collection- Setting
_status: 'draft'alone does not skip required field validation; usedraft: truefor that
Draft API Examples
// Save as draft (only versions table updated)
await payload.update({
collection: 'pages',
id,
data: { title: 'WIP' },
draft: true,
})
// Publish (main collection updated)
await payload.update({
collection: 'pages',
id,
data: { _status: 'published' },
})
// Read latest version (draft or published)
await payload.findByID({
collection: 'pages',
id,
draft: true, // returns newest version from versions table
})
REST equivalent: POST /api/pages?draft=true
Controlling Who Can Read Drafts
Critical:
draft: trueon read does NOT filter by_status. Use Access Control.
access: {
read: ({ req }) => {
if (req.user) return true // logged-in: see everything
return { _status: { equals: 'published' } } // guests: published only
},
}
Migration gotcha: existing documents before drafts was enabled won't have _status. Allow both cases:
return {
or: [
{ _status: { equals: 'published' } },
{ _status: { exists: false } },
],
}
Controlling Who Can Publish
Use update access control with a query constraint on _status:
access: {
update: ({ req: { user } }) => {
if (!user) return false
if (user.role === 'admin') return true
// editors can only update drafts (not published docs)
return { _status: { equals: 'draft' } }
},
}
This also suppresses the Publish/Unpublish buttons in Admin UI for non-admins.
Scheduled Publish
Enable with versions.drafts.schedulePublish: true. Requires wiki/payloadcms/jobs-queue to be running — scheduled events are queued as background jobs.
Unpublishing & Reverting
- Unpublish → sets
_status: 'draft'on the main collection document - Revert to published → creates a new version reflecting last published state (draft history is preserved)
Key Takeaways
draft: truecontrols validation bypass + write location (versions table only)_status: 'published'controls publish state — always overridesdraft: true- First document creation always writes to main collection regardless of
draftparam - Read with
draft: truereturns the newest version (could be draft or published) - Access Control is required to hide drafts from unauthenticated users
schedulePublishrequires the Jobs Queue to be configured and running- Adding drafts to an existing collection → old docs have no
_status; update AC accordingly
Related
- wiki/payloadcms/versions-autosave
- wiki/payloadcms/access-control
- wiki/payloadcms/jobs-queue
- wiki/payloadcms/admin-preview
- wiki/payloadcms/live-preview
Sources
raw/versions__drafts.md— https://payloadcms.com/docs/versions/drafts