Guide 05 · Developer docs

Content types and custom entities

Which built-in type fits which purpose, how categories, tags, slugs, custom URLs and SEO settings behave across them, how revisions and publishing gate what the public sees, how to model a domain the platform has no type for, and where uploaded files live.

L1–L3
Unit 03 · Revisions, publishing and approval

Published, active and draft: the two gates

Whether a visitor sees a record, and which content they see, are decided by two separate fields: the published date and the active revision. This page explains each gate, gives the truth table and shows how to tell the causes apart.

Who this is for. Developers and site builders chasing "it is saved but the site has not changed" or "it was approved but the page is a 404". After this page you can read a record's published date and active revision and say what a visitor sees.

A record can be published with a newer version or a draft pending, and it can hold an approved version while not being published at all. The two are set by separate code and neither moves the other, which is the most common cause of "it is saved but the site has not changed" or "it was approved but the page is a 404".

Gate one: published

A publishable record has a published date. Every query made for a visitor against a publishable entity carries the condition published IS NOT NULL AND published <= NOW(), compared against the database's own clock. An empty date, or one still in the future, hides the record: its URL answers 404 and listings leave it out.

  • Who it applies to. Anonymous visitors and members, always. Backend users bypass it with ?retrieveUnpublished=1, or whenever their setting "Show unpublished" (Globals.admin.showUnpublishedRecords) is on. It is on by default, each user can change it, and its help text reads "Also affects records retrieved from the API using an API key associated with the user."
  • Custom entity records. A record whose definition is not publishable always passes a normal record read, whatever its own published field holds.
  • The unpublish date. unpublishAt plays no part in this condition. It takes effect only through the scheduled-publishing worker, which clears published once the date has passed; see Scheduled publishing and the timezone. The admin has no field for it; it is set through the API.
Check signed out

Signed in to the admin, or reading the API with your own key, you see unpublished records by default. Neither proves what the public sees. Load the URL signed out, in a private window, before concluding that a record is live.

Gate two: the active revision

The active revision decides which content renders, independently of gate one. A record's newest revision and its active revision can differ: a version saved without activating it, or a rollback, leaves the active revision on an older version. The API shows the difference as lastRevision against activeRevision.

A draft can never be the active revision, so a draft never renders publicly, whatever the published date says. The kinds of revision and the save actions are on Revisions and the active revision.

Neither gate opens the other

Activating a revision never publishes the record, and publishing never chooses a revision. The code that sets the active revision, an approval workflow's final transition included, does not touch published, and setting published does not touch the active revision. A record that has passed every approval but has no published date is still a 404.

The truth table

Published dateActive revisionWhat a visitor sees
In the pastVersion 3; version 4 saved but not activatedVersion 3. This is "I saved it and nothing changed".
In the pastVersion 3; an author's draft pendingVersion 3. The draft never renders.
EmptyAny, even a version an approval workflow activatedA 404. Activating never publishes.
In the futureVersion 3A 404 until the date passes, then version 3, with nothing more to do.
In the past, with an unpublish date that has passedVersion 3A 404 once the worker has run (every minute) and cleared the published date. Pages, books, units and book pages only.
AnyAny, on a custom entity record whose definition is not publishableVisible to a normal record read.

Telling the causes apart

  1. Load the URL signed out, in a private window. A backend user's session bypasses gate one by default.
  2. A 404 signed out points at gate one: the published date is empty, still in the future, or was cleared by an unpublish date. If the date looks right but the record goes live early or late, read the timezone section of Scheduled publishing and the timezone.
  3. A 200 with the old content points at gate two: the change was saved as a version that is not active, or as a draft. Make the version you want the active revision; with an approval workflow, move its branch to the last step.
  4. From an integration, read the record's published, activeRevision and lastRevision through the API; Versioned content and the live revision shows the response.
Go deeper

Was this page helpful?

Your answer goes to the docs team.