Overview
The multi-tenant CMS toolkit. Content rows live in the Convex deployment
(packages/convex); this package owns everything that gives those rows meaning —
the field descriptors that define every content shape, the editor primitives the
admin app mounts at /cms, the block render layer the storefront uses, and the
cache taxonomy both sides of the invalidation contract share.
Built on Payload 3.x before the Convex migration — see
.specs/2026-05-30-convex-migration/in the repo for that history. There is no Payload (and no database connection) anywhere in the current package.
For the canonical reference, see the README on GitHub.
Why
A single deployment serves many tenants, and each tenant needs its own pages, articles, navigation, business data, and per-product/collection metadata. This package exists so the platform has exactly one canonical definition of CMS content:
- One schema, many tenants. Every content table keys on the shop's id
(shop == tenant). The field descriptors here generate the Convex table
validators, the editor-action wrappers, and the storefront read-contract types
(
pnpm cms:gen), so the editor, the read contract, and the storage schema can never drift apart. - Shopify-aware blocks, no Shopify dependency in the CMS. The block model is
defined here; data loaders for
collection/vendors/overviewblocks are injected by the storefront at theBlockRendererboundary. - Cache invalidation by construction. The
cmstag taxonomy is declared once (cache-descriptor.ts, free ofserver-only) and consumed from both sides: the Next.js read adapter (./cache) and the Convex revalidation pipeline, which derives identical tags from each publish event.
In this section
- Overview — this page
- API — the surviving pure helpers (
resolveLink) and where reads went - Blocks — block model and the
BlockRendererdispatch component - Collections — content collections, descriptors, and editor access
- Editor — the manifest-driven authoring stack
- Responsive fields — per-breakpoint values, device presets, and the reusable primitive
- API Reference — auto-generated from TypeScript source