Skip to content
Content
Skill

/content-models

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

BOOST
From plugin
webiny-js
8k76 skills3 MCP
Install
$ npx -y skills add webiny/webiny-js --skill content-models --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/content-models

Context preview

The summary Claude sees to decide when to auto-load this skill.

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

SKILL.md

content-models.SKILL.md
name: webiny-api-cms-content-models
description: >
  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

| Method | Purpose | | --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | `.public({ modelId, name, group })` | Creates a public model (accessible via Read API). `modelId` is the internal DB identifier. `group` organizes it in the Admin sidebar. | | `.description("...")` | Model description shown in Admin UI | | `.fields(fields => ({ ... }))` | Define all fields using the fluent field builder | | `.layout([["field1", "field2"], ["field3"]])` | Arrange fields in rows in the Admin editor. Each inner array is one row. | | `.titleFieldId("name")` | Which field to use as the entry's display title | | `.descriptionFieldId("message")` | Which field to use as the entry's description | | `.singularApiName("Product")` | Singular name for GraphQL queries (e.g., `getProduct`) | | `.pluralApiName("Products")` | Plural name for GraphQL queries (e.g., `listProducts`) | | `.singleEntry()` | Makes the model a singleton (only one en

Read more
Ships withwebiny-js

Open-source content platform. Self-hosted on AWS serverless. Built as a TypeScript framework you extend with code, not a closed product you configure through a UI. Runs on Lambda, DynamoDB, S3, and CloudFront inside your own AWS account. Scales automatically.

Get the whole plugin
Stats
8,049
Stars
682
Forks
Active
Maintenance
TypeScript
Language
1d ago
Last commit
8y ago
Created
3d ago
Added

Repo: webiny/webiny-js

Other skills on webiny-js.