Content Model
content models, authorable shape, get_content_modelDefinition
The authorable shape of a component's content — what an author fills in: a headline, a proof point, a CTA, an image, and how many of each — defined once and decoupled from where the content is stored or how any channel displays it
One of the Core's three questions. Schema answers what a component can do, tokens answer what values it renders with, and content model answers what an author fills in. Authority runs one way: a schema change can force a content model change, never the reverse. A contentModel slot has sat on cwds's Component Contract records since 2026-09-18 (PR 55), beside anatomy and the token contract; the concordance had named the gap the day before.
What an author fills in, named without reference to the dialog that collects it or the block that renders it. The AEM dialog and the EDS document table are two adapters over one content model.
What it holds, and what it points to
In the Core draft's accordion:
{
"component": "accordion",
"fields": {
"allowMultipleOpen": { "type": "boolean", "seeSchema": "accordion.props.allowMultipleOpen" },
"treatment": { "type": "string", "seeSchema": "accordion.props.treatment" },
"items": {
"type": "array", "min": 1, "max": 30,
"item": {
"header": { "type": "string" },
"preview": { "type": "string" },
"body": { "type": "composable-content", "seeSchema": "accordion.slots.items[].body" },
"defaultOpen": { "type": "boolean", "seeSchema": "accordion.slots.items[].defaultOpen" }
}
}
}
}
- It owns field type and cardinality (
min/max). Cardinality is an authoring limit and needs no matching schema entry. - It points, rather than restates. A composable field names its schema slot
(
seeSchema) for what may nest inside it, and how deep. - Every prop gets a mirrored field, since schema declares the option but gives the author's choice nowhere to be stored. A prop with no plausible field is probably a token contract touchpoint instead.
- It holds no rules. Required-ness, nesting and cross-field constraints (at most one
defaultOpenwhenallowMultipleOpenis false) live in schema. Content model holds the fields a rule relates, never the rule.
Two designs, one idea
- In the Core draft, content model is its own file. So it carries no
requiredflag: that fact is on the schema slot, and a second copy would drift from it. - In cwds, schema and content model share one record (its ADR-0004). So each content
part carries
required, meaning the contract obliges the author to supply it. With one copy there is nothing to drift, and whether an authoring surface actually enforces it is recorded per realization. - Vocabularies differ too:
- Field types:
string | boolean | array | composable-contentin the draft, andtext | rich-text | image | link | list | numberin cwds. - Cardinality:
min/maxin the draft, and prose in cwds. - Part names: the estate accordion's parts are
blade,label,body,default-openandexpand-all. The last is the nearest real counterpart toallowMultipleOpen.
- Field types:
When a component gets two
Only for a genuine variant, a fork in what the component can do, where
the data shape changes (each item needing a completionCriteria, say). As of 2026-09-25 none
does: cwds maps every observed option to a prop (35) or a treatment
(2), and none to a variant. The look-alike is a numbered multi-step layout, which is a
pattern (several components composed), not a variant. Two authoring
conventions (one item or many, an optional field used or not) are one content model.
What uses it
- Authoring: generates the authoring form.
- Storage: whatever persists the content only needs to resolve into this shape.
- Adapters: each extracts this shape from its own storage. In AEM a Sling Model reads JCR
properties; in EDS a block's
decorate()reads a document table. - Validation: checks authored content against the shape and schema's constraints before publish.
- Agents: reach it through the MCP tool
get_content_model. - Render: consumes the resolved object together with the brand's tokens.