Skip to content

Editor workflow: per-entry 'Ready to publish' flag + 'Publish all marked' action (beyond branches) #1541

@nurkamol

Description

@nurkamol

Use case

We run a marketing site on Keystatic in GitHub mode. Editors make 5–20 small content edits throughout the day (typo fixes, copy tweaks, swapping a tagline, adding a testimonial, etc.). Today, every Save commits straight to main, which:

  • Triggers a fresh production build per Save (Cloudflare Workers Build, in our case — but the same applies to Vercel, Netlify, etc.).
  • Clutters git history with one micro-commit per change ("Update Hero", "Update Hero", "Update Hero", …).
  • Means a typo in any save ships to production immediately.

What's already possible

We know about branchPrefix + branch-based editing — we use it, and PREVIEW.md in our repo documents a workflow where editors pick a long-lived cms/staging branch in the picker, save many times, then merge a PR to publish.

That does solve the deploy-per-save problem, and we recommend it as the answer today. Thank you for that primitive — it's the foundation.

The UX gap

Non-technical editors still need to:

  1. Remember to flip the branch picker to cms/staging before every session (easy to forget; defaults to main).
  2. Leave Keystatic and go to GitHub to open + merge the PR to publish.
  3. Understand what "merge a PR" means.

For technical users this is trivial. For marketing/content editors who have never opened a PR, it's the bottleneck — they often default to editing on main because the picker is right there.

Proposed feature

A first-class "draft → publish" workflow built on top of the existing branch primitive, expressed in admin-friendly language:

  1. A per-entry "Ready to publish" flag in each entry's Save dialog (or as a toggle in the entry form). When unchecked, Save commits to a staging branch. When checked + Save, the entry is marked as ready in the staging branch.
  2. A dashboard surface listing entries currently staged (changed on the staging branch vs. main), with their "Ready to publish" status.
  3. A single "Publish all ready" / "Publish all changes" button that merges the staging branch into the production branch (i.e. opens + auto-merges the PR via the GitHub App).
  4. Optional: a defaultBranch config (e.g. "cms/staging") so the picker doesn't default to main — this alone would already remove a big footgun.

The branch primitive stays exactly as it is; this is purely a UX layer on top, so technical users who prefer raw branches lose nothing.

Why this isn't easily DIY-able

We can — and probably will — build a custom admin page that lists open cms/* branches and exposes a merge button via the GitHub App token. But:

  • Re-implementing the auth Keystatic already does on a sibling route is non-trivial.
  • It's a separate admin surface that editors have to remember exists.
  • It drifts as Keystatic evolves.

A first-class flow inside Keystatic itself would be a much better fit, and would benefit every team running Keystatic at any reasonable editing volume.

Smaller-scope wins, if a full design is out of scope

Either of these alone would already be a big improvement:

  • defaultBranch config option — pick cms/staging so editors don't accidentally land on main.
  • A "Publish to production" action in the branch picker when the current branch is cms/* — one click to open + merge the PR (instead of leaving Keystatic).

Happy to test any of this on a live editorial site if useful.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions