The Visual Website Builder
You Actually Own. React + Next.js, low-code, self-hosted. Your data, your infrastructure, every feature included.
© ChaiBuilder. All rights reserved.

A global block is a section built once and used on many pages: a site header, a footer, a CTA band, a disclaimer. Edit it in one place and every page that uses it changes.
The mechanism is worth knowing, because it explains every rule that follows. A global block is two objects, not one:
Once you see it as "a page you can't visit, plus pointers to it", the rest of this page is consequences.
Some of the product's internals and older material call these partials. Same feature - the user-facing name is global block.
Two routes, both in the builder:
Either way you can attach a description and tags. Neither is decoration: the description is what the AI reads to decide whether a global block is relevant, and tags are how the add-block panel filters the list once a site has thirty of them.
The reference is not a wrapper that fetches something at runtime. When a page is loaded, the server inlines the global block's tree in place of the reference before rendering begins:
Stored page What renders
├── Reference → header ──► ├── Section (from the global block)
├── Section │ └── Nav
└── Reference → footer ├── Section
└── Section (from the global block)
Three details follow from inlining:
Draft renders inline the global block's draft; live renders inline its published version. That single sentence explains most global-block confusion in practice.
One global block renders identically on every page that uses it. There are no per-page variants, no overrides, and no props to pass in from the consuming page.
This is a deliberate constraint, not a missing feature: a variant would be a different tree, and a different tree is a different global block. If two pages need different wording of the same band, you have two global blocks - or the content belongs inline on each page.
A useful test before creating one: is this used on two or more pages, with identical content? If not, keep it inline. A single-use global block is indirection with no payoff, and it makes the page harder to edit for the next person.
A global block has its own draft and published versions, so publishing a page does not publish the global blocks it uses, and vice versa.
So the failure looks like this: you build a beautiful footer, publish the page, and the live site has no footer. The page was published; the footer was not.
To make invalidation possible, each page records which global blocks it uses, transitively. That record is also what answers "where is this used?" before you change something.
A page can use a global block, and that global block can use one more. The second level must not contain further global blocks. Two levels, hard limit.
Cycles are prevented in two places. In the builder, a global block that would create a loop or exceed the depth limit is shown but disabled in the add panel, with the reason, so the constraint is visible rather than mysterious. At render time the same rules are enforced again defensively - a reference that would loop is simply left unexpanded, which matters for pages authored outside the builder where no add-time check ever ran.
| Symptom | Usual cause |
|---|---|
| Edited the global block, live pages unchanged | The global block itself was never published |
| Renders in the builder, missing on the live site | Same cause: draft exists, published version does not |
| A section disappeared from many pages at once | A global block was unpublished, taken offline, or deleted |
| The outline flags a reference as missing | The global block it points at was deleted. The reference stays in the page JSON on purpose, so removing it is deliberate |
| Content vanished only in preview | The global block is in the trash; soft-deleted global blocks are excluded from draft renders |
| Cannot add one from the panel | It would create a cycle or exceed two levels of nesting. The disabled entry states which |
| Two pages need slightly different versions | Working as designed. Make a second global block, or keep it inline |
