Content models are a layer above data models, with the primary purpose of defining the content management experience presented in a store’s dashboard.

This two-tiered approach makes it easier to separate concerns between the database schema, API functionality, and administrative workflows. See our guide on content models vs data models for more details.

You can create a new content model manually, or by using the following CLI command:

swell create content

→ See the CLI reference for more details and options.

Here's an example of a new content model:

content/things.json
{
  "collection": "things",
  "fields": [
    {
      "id": "name",
      "type": "text"
      "required": true
    },
    {
      "id": "description",
      "type": "long_text"
      "hint": "Describe this thing in 2-3 sentences"
    }
  ]
}

Notice the difference between content and data model configurations. Content models prefer UI-oriented field types, which for example can specify short vs long text, and field ordering to display in the admin dashboard, while data models are purely schema-oriented to structure the database and related APIs.

In the above example, the things collection is not standard, therefore a new data model and collection will be established by the app. If it did exist, then the platform would automatically enhance the underlying data model associated with that collection.

All model collections are private by default, but to support accessing data from the frontend API you can declare individual fields or entire models as public, along with specific query parameters that can limit the range of fields returned using a public key.

Here’s an example model with a public field:

{
  "collection": "vendors",
  "label": "Vendors",
  "fields": {
    "name": {
      "type": "string",
      "required": true,
      "public": true
    },
    "active": {
      "type": "bool"
    },
    "description": {
      "type": "string"
    }
  },
  "public_permissions": {
    "query": {
      "active": true
    },
    "expands": {
      "products": {
        "url": "/products",
        "params": {
          "vendor_id": "id"
        },
        "data": {
          "active": true
        }
      }
    }
  }
}

With at least 1 public field declared, all records can be accessed by the frontend API, with only the public fields being returned in a response. In addition, you can limit the range of results to only include active records using public_permissions, and specify how expand parameters should be treated for the collection in a public scope.