Skills

Webiny API Cms Content Models

Creating Headless CMS content models via code using the ModelFactory pattern.

Install

npx skills add webiny/webiny-js --skill webiny-api-cms-content-models -g -a claude-code -y
Repository
webiny/webiny-js8.1k
Category
Design
Updated
5d ago
License
See repository
Context cost
Mediumabout 3,000 tokens
Runs scripts
No, instructions only

What it does

Creating Headless CMS content models via code using the ModelFactory pattern. Use this skill when the developer wants to create, modify, or understand content model definitions, define fields and validators, set up reference fields between models, configure field layouts (including nested layouts inside object or dynamicZone fields), pick the correct Admin UI renderer for a field type (textInput/textInputs, lexicalEditor/lexicalEditors, file/files, objectAccordionSingle/objectAccordionMultiple, etc.), or work with the ModelFactory builder API. Also covers field types (text, longText, number, boolean, datetime, asset, file, ref, object, richText, dynamicZone), list (array) fields via .list() and the singular-vs-plural renderer rule, the mandatory datetime subtype (dateOnly/timeOnly/withTimezone/withoutTimezone), validation (required, unique, email, pattern, minLength, maxLength, gte, predefinedValues), single-entry (singleton) models via .singleEntry(), model/field tags via .tags(), and field rules via .rules() for access-control and conditional visibility/editability. Includes the correct `fields` projection syntax when querying entries via the SDK: `ref` fields use double-`values.` nesting (e.g. `values.author.values.name`) because they resolve to another entry, while `object` and `dynamicZone` sub-fields are inline and use a single `values.` (e.g. `values.author.name`), getting this wrong silently returns null.

Creating Content Models via Code

TL;DR

Content models are created using the ModelFactory pattern. You define a class implementing ModelFactory.Interface, use the fluent ModelFactory.Builder API to declare fields, validators, layout, and API names, then export with ModelFactory.createImplementation(). Register in webiny.config.tsx as <Api.Extension>.

The ModelFactory Pattern

Every code-based content model follows the same structure:

import { ModelFactory } from "webiny/api/cms/model";

class MyModelImpl implements ModelFactory.Interface {
  async execute(builder: ModelFactory.Builder) {
    return [
      builder
        .public({ modelId: "myModel", name: "My Model", group: "ungrouped" })
        .description("Description of the model")
        .fields(fields => ({
          // field definitions here
        }))
        .layout([/* row definitions */])
        .titleFieldId("fieldId")
        .singularApiName("MyModel")
        .pluralApiName("MyModels")
    ];
  }
}

export default ModelFactory.createImplementation({
  implementation: MyModelImpl,
  dependencies: []
});

Register in webiny.config.tsx:

<Api.Extension src={"/extensions/MyModel.ts"} />

YOU MUST include the full file path with the .ts extension in the src prop. For example, use src={"/extensions/MyModel.ts"}, NOT src={"/extensions/MyModel"}. Omitting the file extension will cause a build failure.

YOU MUST use export default for the createImplementation() call when the file is targeted directly by an Extension src prop. Using a named export (export const MyModel = ...) will cause a build failure. Named exports are only valid inside files registered via createFeature.

Model Configuration Methods

Read the whole SKILL.md on GitHub

More in Design