How-to

Publish a site and keep drafts private

Visitors see only what you've released. You deploy as often as you like, check the result, and release everything at once.

The one rule that makes this work: a public read rule with labelFilter: "published". Without the label filter, visitors always see the latest upload, and deploying is releasing.

1. Create the public rule (once)

The first deploy can create it for you. Deploying with a label and --public creates a rule with labelFilter: "published":

bash
export WREN_URL=https://wren.aemwip.com
export WREN_API_KEY=wren_…                       # or: wren auth login
wren deploy ./dist --tree mysite --label preview --public

Or create it yourself through the API:

http
POST /api/v1/permissions
{"principal":"*", "resource":"tree:mysite", "access":"read", "labelFilter":"published"}

2. Deploy changes as a preview

bash
wren deploy ./dist --tree mysite --label preview

Changed files (compared by SHA-256) are uploaded as new versions of the same documents and labelled preview. Visitors keep seeing the published versions. A file that has never been published returns 404 publicly; it never shows a draft.

3. Check the preview

The preview is visible only through the private API with your key. Adding ?label=preview to a public URL has no effect: the public rule's label filter always wins.

bash
curl -H "Authorization: Bearer $WREN_API_KEY" \
  "$WREN_URL/api/v1/tree/mysite/index.html?label=preview"

To click through a preview in a browser, sign in to the Admin UI, or put a small proxy that adds your key in front of the private route (keep it off the public internet).

4. Promote

bash
wren promote mysite --from preview

This moves published to the preview version of every document in the tree in one transaction, so visitors never see a mix of old and new files. Under the hood it's POST /api/v1/tree/mysite/_promote {"from":"preview"}. See why promote is atomic.

Roll back a bad release

Nothing is overwritten, so rolling back means pointing published at older versions again. The simplest way is to give every release a name when you promote it:

bash
# on every release, also tag the versions you're about to publish
wren promote mysite --from preview --label release-2026-10-04
wren promote mysite --from preview

# later: roll back by promoting the older release label
wren promote mysite --from release-2026-10-04

Files that weren't part of that release keep their current published version. To roll back a single file instead, use POST /api/v1/{collection}/{id}/labels {"label":"published","version":3}.

Already public without a label filter?

Label what's live first, then add the filter. Doing it the other way round takes the site offline until the next promote.

bash
wren promote mysite                                  # current versions → published
wren permissions list                                # find the tree:mysite rule
wren permissions update <rule-id> --label-filter published

Pitfalls

  • Data your pages fetch needs the same treatment. If the site reads a JSON collection, give that collection's public rule a label filter too, or keep the JSON files in the tree so one promote releases both.
  • Live data shouldn't wait for a promote. Scores or feeds that should appear immediately belong in a collection whose public rule has no label filter. See the tournament tracker.
  • CDN caching: successful public responses may be cached for up to a minute. Errors aren't cached.