vault backup: 2026-05-15 16:56:10
This commit is contained in:
parent
45a9d24bed
commit
dacd2beb73
3 changed files with 150 additions and 0 deletions
|
|
@ -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 |
|
||||
|
|
|
|||
149
wiki/payloadcms/versions-drafts.md
Normal file
149
wiki/payloadcms/versions-drafts.md
Normal 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
|
||||
Loading…
Add table
Reference in a new issue