Publishing
The Content Delivery API never reads what editors are working on. It reads published snapshots: copies taken at the moment something was published, held in a delivery environment. Most surprises when building a site (“I changed it and nothing happened”) come down to the gap between a draft and its snapshot.
Drafts and snapshots
Section titled “Drafts and snapshots”Everything in an authoring environment is a draft. Saving a Component or a page changes the draft and nothing else. Publishing takes a snapshot of the draft and copies it into a delivery environment, and the Delivery API serves only that snapshot.
Each publishable item has one of four states, shown in the app:
- Draft: never published.
- Published: a snapshot is live and matches the draft.
- Modified since publish: a snapshot is live, but the draft has changed since. Visitors still see the snapshot.
- Unpublished: it was published and has been taken down. It still exists as a draft.
Two things are publishable: Components and Experience nodes (pages). Contracts and Templates are not published on their own. They travel with the content that uses them.
What a publish includes
Section titled “What a publish includes”Publishing an item publishes its dependency closure: the item plus everything it needs to render. For a page, that is the Component bound to it, every Component that Component references, and so on however deep the chain goes. Before anything is written, the app shows the whole plan. Each item can be left out, and an item that fails validation cannot be included until it is fixed.
The closure follows what an item needs, not what sits near it. Some consequences:
- Publishing a page does not publish its child pages. Each page is published on its own.
- A Component that no page references (a shared header or footer your site fetches by external id, for instance) is published on its own.
- Inline values are part of their parent’s document, so they are published with it and never separately.
- Files and images in Blob fields get a permanent public URL the first time they are published. Unpublishing the content that used a file does not take that URL down.
A reference to something that is not published (it was left out of the plan, or later
unpublished) is not an error at delivery. It arrives with unresolvable: true and no content,
and your renderer decides whether to omit it or show a placeholder.
Why an edit needs republishing
Section titled “Why an edit needs republishing”A snapshot is frozen. Editing the draft of anything already published changes nothing on the live site until it is published again.
The rule is about which snapshot holds the value you changed:
- Editing a Component’s own fields needs that Component republished. The pages that reference it do not need republishing, because they read the Component’s current snapshot when they are delivered.
- Editing a page’s own payload (its Template, its settings, which Component it binds, the contextual values set on that binding) needs the page republished.
- Renaming or moving a page needs the page republished, since a path is part of the snapshot.
- A page’s order among its siblings, its title and whether it is excluded from the sitemap are all frozen at publish, so changing any of them needs a republish too.
Republishing a page re-freezes its whole plan, so it is also a way to push out a changed Component the page depends on.
What delivery reads
Section titled “What delivery reads”When a request arrives, the Delivery API reads the published snapshots of the pages and Components
it needs, and expands references to the resolve depth you asked for. Snapshots store only what was
published, so a response is the same whether the matching draft has been edited since or not.
Responses are cached by the API. Publishing and every other change that can affect a response clears that cache immediately. As a safety net, a cached response is also never more than a few minutes old. If you add your own cache in front of the API, refresh it when content is published; see the getting-started guides for static and server-rendered sites.
What is read live
Section titled “What is read live”A few things are not frozen into snapshots. Delivery looks them up when each request arrives, so changing them changes live pages without any publish:
| What | Why it is live |
|---|---|
| Stream definitions | A stream’s sources, filters and ordering are configuration, read on every query. The Adapter a stream projects its items through is read live too |
| Adapters nested inside other Adapters | An Adapter rule that hands off to a named Adapter reads that Adapter’s current rules |
| Category names and paths | A category’s label, path and group are looked up per request. Which categories an item carries is frozen at publish |
| Audiences | The conditions behind each audience are read per request when a response is personalized |
| Link URLs | A snapshot freezes which page a link points at, not its URL. The URL is composed per request from the target page’s current published path |
| Relayed Presentations | A Presentation copied from a linked page through an Adapter always reflects that page’s current snapshot |
| Content from external providers | Read from the provider, with a short cache |
| Site host names and locale addressing | Routing configuration, applied to every address the API returns |
The Adapter on an ordinary Presentation binding is frozen: editing it changes nothing until the content that uses it is republished. Only a stream’s projection Adapter, and a named Adapter reached from inside another Adapter’s rules, are read live.
Because these are live, changing one changes a published page. A category that has been deleted
arrives with resolved: false, and a link to a page that has since been unpublished arrives with
url: null and resolved: false.
Redirects from renamed paths
Section titled “Redirects from renamed paths”When a published page’s slug changes, or the page moves, the next publish computes its new path and turns the old one into a redirect alias. Requesting the old path then answers:
{ "kind": "redirect", "targetPath": "/coffees/ethiopia-guji", "targetNodeId": "0f6d…" }Follow it: redirect the visitor, or render the target. Chains of redirects are already collapsed on
the server, so targetPath is always a real page. Nothing in your site needs to know a path used
to be something else. Aliases can be reviewed and deleted in the app, under Configure → Sites.
A page can also be a redirect on purpose: an Experience node whose payload is a Redirect answers the same shape.
Workflow gating
Section titled “Workflow gating”An organization can assign an editorial workflow to a folder or a branch of the Experience tree. Content governed by a publishing workflow can be published only from its Approved state, and while it sits in a review step or in Approved its content is locked. Publishing publishes the version that was reviewed, not any later edit.
In the publish plan, an item that its workflow does not yet allow is shown as blocked and left out, and the rest of the plan can still be published. The same rule applies to a management key: it acts as its role, so a page awaiting approval cannot be published by a script any more than by a person.
Publishing also needs the Publish permission on the item’s folder or tree branch. That is a separate permission from Edit, so an organization can have editors who cannot make content live.
Publishing through the API
Section titled “Publishing through the API”A management key with content.management.publish can publish in two steps: request a plan, then
execute it. The plan reports the same blockers the app shows. See
Content as code.