Skip to content
Launch
Esc
↑↓navigate↵open⌘Jpreview
On this page

Architecture

The apps, the shared packages, and where each CMS ends and the shared front-end code begins.

apps/              Deployable apps: CMS installs, vinext front-ends, the MCP Worker, this docs site
packages/          Shared libraries: content model, UI, adapters, Access helpers, logging, MCP
wordpress-shared/  Patronage's WordPress code that both installs load, and the deploy kit
docs/              Engineering notes: decision records in docs/adr/, research in docs/spikes/

Apps

App What it is
cms-wordpress-headless WordPress in Docker as an editor and a WPGraphQL API. It renders nothing public.
web-wordpress The vinext front-end for headless WordPress, deployed as a Worker.
payload Payload as one vinext app on Workers: the admin, plus front-end pages that read through the Local API.
cms-wordpress-timber A traditional WordPress install with a Timber theme. It shares design tokens with the others, not components. See Traditional WordPress.
mcp Launch’s deployment of the MCP gateway Worker, behind Access, with its WordPress and Payload connectors. See MCP server.
docs-site This site.

Shared packages

  • content-model: the CMS-neutral shape of a page and its sections.
  • ui: shadcn/ui components on Tailwind 4, the Section, Container and Typography primitives, and one component per content-model block. They take plain props and know nothing about WordPress or Payload. See Shared UI.
  • adapter-wordpress and adapter-payload: map each CMS’s data to content-model. See CMS-neutral sections.
  • access: provisions the Access applications, calls the CMS through Access, and verifies Access tokens. See Lock the CMS behind Cloudflare Access.
  • logging: the Worker wrapper that prints one wide event per request, and the script that provisions a site’s log bucket. WordPress’s side is the patronage-logging mu-plugin. See Logging.
  • sections-preview: a parity test and a static page that render the same page from both CMSs side by side.
  • demo-content: the placeholder images and their alt text that every CMS’s seed uses.
  • images: serves CMS images through the Cloudflare Images binding, on one same-origin route.
  • mcp-core, mcp-wordpress and mcp-payload: the MCP gateway and its two connectors, built for npm under @patronage. apps/mcp deploys them. See MCP server.

Shared WordPress code

Both WordPress installs load the same Patronage code from wordpress-shared/:

  • patronage-fields: the ACF field groups, post types, rich-text shortcodes, the form model and the demo seed.
  • patronage-access: the mu-plugin that verifies Cloudflare Access sign-ins. Only the headless install uses it, since the Timber install serves its public site from WordPress.
  • patronage-logging: the mu-plugin that records WordPress events. See Logging.
  • wp-deploy: the deploy kit. See Deploying WordPress.

Where the CMS stops

Each CMS has an adapter that maps its data to content-model. Rich text and editor field definitions stay CMS-specific: the adapter renders rich text and passes it to the shared components as children. That keeps ui free of any one editor’s format.

Locking the CMS down

The pattern every reference follows:

  1. The CMS admin and API are behind a Cloudflare Access application.
  2. The front-end Worker reaches the CMS with an Access service token, or (for Payload) through the Local API in the same Worker.
  3. The CMS tells the front-end what changed through a signed revalidation request, so public pages stay cached until an edit is published.

Was this page helpful?