vault backup: 2026-05-15 16:56:10

This commit is contained in:
Vadym Samoilenko 2026-05-15 16:56:10 +01:00
parent 45a9d24bed
commit dacd2beb73
3 changed files with 150 additions and 0 deletions

View file

@ -146,3 +146,4 @@
| [[wiki/payloadcms/troubleshooting\|Troubleshooting Common Issues]] | Dependency mismatches (duplicate packages, monorepos), "Unauthorized" cookie debug, --experimental-https HMR WebSocket fix, DB password encoding | raw/troubleshooting__troubleshooting.md | 2026-05-15 |
| [[wiki/payloadcms/typescript-plugin\|TypeScript Plugin (Experimental)]] | `@payloadcms/typescript-plugin` — IDE path validation, export validation, autocomplete, go-to-definition for PayloadComponent import strings; VS Code workspace TS setup | raw/typescript__ts-plugin.md | 2026-05-15 |
| [[wiki/payloadcms/versions-autosave\|Versions — Autosave]] | Autosave config (interval/showSaveDraftButton), single-version upsert storage strategy, `autosave` arg on Local API update, requires versions+drafts | raw/versions__autosave.md | 2026-05-15 |
| [[wiki/payloadcms/versions-drafts\|Versions — Drafts]] | draft param vs _status field, write location table (versions table vs main collection), access control for read/publish, scheduled publish via Jobs Queue | raw/versions__drafts.md | 2026-05-15 |

View file

@ -0,0 +1,149 @@
---
title: "Versions — Drafts"
aliases: [payload-drafts, draft-publish, payload-draft-api]
tags: [payloadcms, versions, drafts, publish, access-control]
sources: [raw/versions__drafts.md]
created: 2026-05-15
updated: 2026-05-15
---
## Overview
Drafts build on [[wiki/payloadcms/versions-autosave|Versions / Autosave]] to let you save changes without publishing them immediately. Requires `versions` to be enabled first.
```ts
// 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'` → overrides `draft: true` and updates the main collection
- Setting `_status: 'draft'` alone does **not** skip required field validation; use `draft: true` for that
## Draft API Examples
```ts
// 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: true` on read does NOT filter by `_status`. Use Access Control.
```ts
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:
```ts
return {
or: [
{ _status: { equals: 'published' } },
{ _status: { exists: false } },
],
}
```
## Controlling Who Can Publish
Use `update` access control with a query constraint on `_status`:
```ts
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|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: true` controls **validation bypass** + **write location** (versions table only)
- `_status: 'published'` controls **publish state** — always overrides `draft: true`
- First document creation always writes to main collection regardless of `draft` param
- Read with `draft: true` returns the **newest version** (could be draft or published)
- Access Control is required to hide drafts from unauthenticated users
- `schedulePublish` requires 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|Versions — Autosave]]
- [[wiki/payloadcms/access-control|Access Control]]
- [[wiki/payloadcms/jobs-queue|Jobs Queue — Overview]]
- [[wiki/payloadcms/admin-preview|Admin Preview & Draft Preview]]
- [[wiki/payloadcms/live-preview|Live Preview — Overview]]
## Sources
- `raw/versions__drafts.md` — https://payloadcms.com/docs/versions/drafts