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.

ChaiBuilder is optimized for content-heavy, public-facing sites: pages are static once built, and edits go live by invalidating exactly what changed. This page explains the cache layers and the publish-to-live pipeline, so you can reason about freshness on any hosting target.
This is standard Next.js SSG + ISR (the public catch-all route is force-static), so
every host that supports Next.js caching supports it - Vercel natively, Node servers via
the on-disk cache, Cloudflare via the OpenNext incremental cache.
Cache entries are tagged, and every content operation reports which tags and paths it touched. After each builder action, the affected tags and paths are revalidated:
| You do | What revalidates |
|---|---|
| Publish a page | that page's path and cache tags |
| Change site settings / theme | the site-wide settings tag, plus the page layout tree |
| Publish a CMS item (e.g. a blog post) | pages rendering that collection's content |
| Publish a partial (shared header/footer) | pages using that partial |
CMS-driven invalidation comes from the starter's Payload wiring: collections listed in the
ChaiBuilder plugin's revalidateCollections (the starter includes its content collections)
revalidate their dependent pages on change. Add your own collections there when custom
content should refresh pages that render it.
Preview uses Next.js draft mode: while previewing, data is fetched fresh per request (a request-scoped memory cache prevents duplicate queries inside one render, but nothing persists). Editors always preview live data; the persistent cache and CDN are only in the published-visitor path.
The starter exposes a revalidation route for cases where content changes outside the
builder - an external system writing to your database, or a script. The route is protected
by a bearer token: set REVALIDATE_TOKEN in your environment and send it on every
request. When the token is unset, the route is disabled and every request gets a 401.
curl -X POST https://www.example.com/admin/api/revalidate \
-H "Authorization: Bearer $REVALIDATE_TOKEN" \
-H "Content-Type: application/json" \
-d '{"paths": ["/pricing", "/blog/my-post"], "tags": []}'
It accepts paths and/or tags (arrays or comma-separated strings) and revalidates each.
Generate the token like any secret (openssl rand -hex 32) and store it wherever the
calling system keeps its credentials.
Custom blocks and data providers run server-side and are not cached by default - keep them fast or cache them. The pattern the platform itself uses:
When writing custom data fetching, follow the same shape: tag your cached queries, and have
whatever mutates the data revalidate those tags (via the route above or revalidateTag in
your own server code).
The ISR cache already makes origin responses cheap, and platform CDNs (Vercel, Cloudflare)
integrate with revalidation automatically. If you add an external CDN in front of a
Node deployment, be careful with HTML caching: the CDN does not know when you publish. Safe
default - let the CDN cache immutable assets (/_next/static, media URLs) and pass HTML
through to the origin, which serves it from the ISR cache anyway.
.next (the ISR
cache lives there).