CWA 2 is a prerelease (2.0.0-alpha), heading for a beta. It runs production sites; configuration can still change between releases, always with upgrade notes. View versions and support
Core Concepts

The Data Model

The seven resource types that form the content graph behind every CWA page — and how they chain together.

Every page in a CWA site is described by a chain of resources stored in the API. Understanding this chain is the most useful thing you can learn about CWA. Key Ideas gives a one-line summary of each term, and the Glossary defines them all.

The Resource Chain

The diagram below shows both paths through the chain — static pages (Route → Page directly) and dynamic pages (Route → PageData → template page):

Key — blue: UI resources with a uiComponent field (you write a Vue template). Violet: resources you define in PHP by extending a CWA abstract. Stone: core structural resources managed by CWA (no code required). Component types are blue but also require a PHP class like PageData. These diagram colours aren't the admin's: the admin uses blue for static pages (see Static Pages).

Route

Maps a URL path to either a Page (for static pages) or a PageData record (for dynamic pages). Also handles redirects.

Page

The content structure rendered inside a Layout. Its uiComponent field maps to your Vue template file.

  • Static page: one page, one URL, its own component groups
  • Template page (isTemplate: true): reused across many PageData records — one per article, product, event, etc. Don't confuse it with a page template, the Vue file a page renders through

PageData

Used for dynamic sections (blogs, events, products). Instead of a Route pointing directly to a Page, it points to a PageData record. That record carries a page field naming the template page (the shared page record) to render, plus the URL's own content fields.

  • Extends AbstractPageData, which provides title and metaDescription for SEO
  • Your custom fields (headline, body, image) live here
  • Its own Route gives it a live URL (e.g. /blog/my-first-post)

Layout

The outer shell of every page — header, footer, navigation. Every Page has exactly one Layout.

  • uiComponent: "CwaLayoutPrimary" → renders your app/app/cwa/layouts/primary.vue
  • Has its own ComponentGroups (e.g. a nav group)

ComponentGroup

A named, ordered list of components that belongs to a Layout, Page or Component. Editors add and reorder its components in the admin.

  • The reference string (e.g. "hero", "nav") is what you use in your Vue template: <CwaComponentGroup reference="hero" :location="iri" />
  • Can restrict which component types are allowed via allowedComponents

ComponentPosition

The record that places one Component in a ComponentGroup and sets its order. It holds exactly one Component, or a binding to a PageData field.

Component

Your custom content items: titles, paragraphs, images, hero sections, navigation links, etc.

  • Rendered by its type: a Title resource renders app/app/cwa/components/Title/Title.vue. Its uiComponent stays empty unless an editor picks a ui/ variant
  • Can be publishable (draft → published workflow)

A Concrete Example

For a blog, a Route points to a BlogArticleData PageData record rather than a Page directly. BlogArticleData carries a page field naming the blog-template template page, which renders through PrimaryPageTemplate.vue. blog-template has a ComponentGroup containing a ComponentPosition with pageDataProperty: "htmlContent" — at render time that position resolves to whatever HtmlContent component is stored on the current BlogArticleData record. This is the template's own blog example. The dashed line in the diagram shows that runtime binding:

_metadata

Every resource the API returns also carries a _metadata object. The module uses it internally; your Vue components read the resource's own fields, such as resource?.data?.title.

Next: Layouts & Pages

Layouts & Pages looks at the two records that shape every page.