Show navigationHide navigation

Multiple deploys (prod, staging, previews)

Each deployment resolves which Git branch serves public content independently. There is no shared cms/published.json. The pointer file path is cms/pointers/<build-id>.json on the pointer ref (see git.publishedPointerBranch in cms/octocms.config.ts), where <build-id> comes from the first set of: VERCEL_DEPLOYMENT_ID, VERCEL_BUILD_ID, GITHUB_RUN_ID, BUILD_ID, otherwise the literal local.

Resolution order#

  1. Per-build pointer file — JSON on the pointer branch (or baseBranch if publishedPointerBranch is unset) at getPointerFilePath(). The payload is { "branch": "<name>", "buildId": "<same id>" }. branch is what public reads use when that ref exists on GitHub.
  2. CMS_BRANCH environment variable — when the pointer file is missing, invalid, or names a branch that does not exist on GitHub.
  3. git.baseBranch from config (e.g. main).

When the pointer file is written#

  • Publish in the CMS writes (or updates) the pointer for this build. The header branch selector only changes where saves go (the cms-active-branch cookie); it does not change what the public site reads until you click Publish.

Environment variables#

VariablePurpose
CMS_BRANCHFallback branch when no valid pointer override exists. Ignored if the branch does not exist on the remote.
VERCEL_DEPLOYMENT_IDPreferred build id for the pointer filename (Vercel).
VERCEL_BUILD_IDSecond choice for build id (Vercel).
GITHUB_RUN_IDBuild id in GitHub Actions.
BUILD_IDSet in CI or any host so each deploy gets a distinct pointer file when Vercel vars are absent.
(none)Pointer path uses local — fine for a single dev machine; set BUILD_ID if several environments would otherwise share the same id.

Branch picker#

Open the menu from the branch chip in the admin header on any /cms screen (including while still on main and before editing content). The list is the base branch plus open pull requests labelled cms-update whose head branch is under cms/*. The first action is Create new branch. The configured publishedPointerBranch is never shown in the list so editors do not select it by mistake.

Recipes#

Production (Vercel)VERCEL_DEPLOYMENT_ID is set automatically; optional CMS_BRANCH=main. Use Publish to point public traffic at a branch for this deployment.

Staging — set a unique BUILD_ID (or run on a CI that sets GITHUB_RUN_ID) per environment so pointer files do not collide with production.

PR preview — each Vercel preview deployment gets its own deployment id, so preview pointers stay isolated.

Migration from cms/published.json#

That path is no longer read. Set CMS_BRANCH to your previous default, or use Publish once so the pointer file exists on the pointer branch for this build.

See also Editorial workflow.