Trial changes with preview deploys
Ship preview commits, promote or discard them, and respect preview rules.
Trial a change before it goes live: commit with preview: true to deploy the same app at https://<slug>--preview.outer.now. Live stays untouched until promotion.
// Trial a change:
{ "tool": "commit", "app": "grocery", "message": "Reorder the list", "edits": […], "preview": true }
// Ship it:
{ "tool": "promote_preview", "app": "grocery" }
// Throw it away:
{ "tool": "discard_preview", "app": "grocery" }
Run the preview loop
- Commit with
preview: trueto refresh the app’s one preview. - Expect the same pipeline as live: install, build, moderation gate, migrations from scratch, then celld deploy.
- Expect an empty namespace: the preview fleet starts with fresh D1/KV/R2 state and never touches live data.
- Share the preview URL for click-through; unlisted previews answer
noindexlike live. - Promote with
promote_previewto fast-forward main and deploy normally. - Discard with
discard_previewto stop the fleet and remove trial state. - Expect automatic discard after 24 hours without requests.
- Pass
preview: truetodeploy_statusanddeploy_logwhen following a preview run.
Respect the preview rules
- Require the owner’s Pro plan for preview commits and promotion; otherwise expect
payment_required. - Count each preview commit as one code change; promotion moves a ref and costs nothing.
- Compare
baseagainst the preview tip on preview commits, not main. - Keep a clean line for promotion; a later live commit blocks it with
conflict. - Recover from
conflictby runningdiscard_preview, committing a fresh preview from the new live version, then promoting. - Respect host capacity
OUTER_PREVIEW_MAX(default 20); past it expectrate_limitedwithretry_after_s. - Never name an app
*--preview; those slugs stay reserved so live and preview URLs never collide. - Discard the active preview before renaming; renames with an active preview refuse.
For the person-side walkthrough, see Preview changes.