Guides
Each Swell store has an editable schema based on models. These are the building blocks that shape each store and house both content and business data. With models, you can customize and capture information within various namespaces of your choosing—allowing you to utilize or access that information in various locations.
Models can be customized by Swell Apps, and from within the Swell dashboard under Developer → Models. To begin customizing your models via API, you’ll need to authenticate your store:
Swell comes with a suite of standard data models and ecommerce business logic out of the box which serves as a foundation for further customization. You can add new fields to built-in models like products and orders, or create entirely new models for your store’s specific needs. Fields can be used to store all the kinds of data you’d expect from a CMS or database, can be rendered in the dashboard for admins to edit, and can utilize formulas for default values.
Swell utilizes two different types of models, each with its own intended functionality:
- Content models work similarly to a CMS and can be used to model editable structured content any way you like.
- Data models are for Swell's built-in commerce functionality and can be customized to suit your business needs.
Content models
- Automatically generate an associated data model if they need to be accessible via their own API endpoint.
- Define field types with input UI components and validation options.
- Content collections and fields have dedicated space in the dashboard for managing items.
- Content models can have their own API endpoint, attach fields to standard data models (e.g. products), or be abstract sets of fields used within other models.
Data models
- Define database field types directly mapping to API structure.
- Editing UI only for standard models.
- All models have a top level API endpoint.
Since data models are low-level configurations with primitive field types, they're best used to store data that will be accessed programmatically or through a custom UI. If you want to provide the ability for admins to edit field values in the dashboard or storefront editor similarly to a CMS, content models are the solution.
Content models are a layer above data models and have a simpler configuration syntax and allow for field values to be editable in the dashboard. They provide most of the functionality you'd expect from a dedicated CMS—with the additional benefit of making content available in the same API as standard models like products. While data models are limited to primitive field types, content models can define input UIs for fields like phone or url to provide a better editing experience.
Content models can be used to:
- Add new fields to existing models that can be edited in the dashboard, like extra details about orders or customers.
- Add new collections of custom content that are available via API, like pages or blogs.
- Create repeatable and modular components that can be used to build custom page layouts with structured content blocks.
{
id: 'product_detail_page', // Required
name: 'Product detail page', // Required
description: "Page displaying a single product", // Optional
collection: "products", // Optional
fields: [
{ ... },
{ ... },
{ ... }
]
}
Content model attributes:
- id is what the model is referred to in code
- name and description are used in the dashboard to help admins understand what the model is and what it is used for
- collection is used to determine where the content model will exist
- fields are the set child fields the model contains
Content models work in a similar way to data models, but they have a simpler definition syntax. Their use is focused on building flexible content structures and an intuitive editing UI within the dashboard.
Manage content models in the following ways:
- From the dashboard, under Developer → Models.
- By configuration in a Swell App.
The collection attribute determines where the model's data is stored, and whether it has an API endpoint.
In a new model
A new collection and an underlying data model is created if the collection doesn't already exist. All objects of the content model will be available at that collection endpoint.
Field IDs can be arbitrary object paths, which allows for logical grouping of things, and reliable paths even when moving fields between the root and field groups.
Let's say we're an upscale beverage maker and want to have a list of ingredients for one of our fine tipples. Defining a content type with an ingredients field and model: 'products' stores the data on a product object at product.content.ingredients.
We want each ingredient to have a name and description, so we'll use a collection field to allow any number of ingredients with those two fields to be added. Collection fields can accommodate other content types using the item_types attribute and passing an array of content type IDs, or define a set of fields that each item in the collection will have. Some CMS call this a 'repeated field'.
// Create the content type
await swell.put('/:content', {
name: 'Product details', // The name shown in the dashboard
description: 'Additional info about the product', // An optional description to help admins understand what this content type is for
collection: 'products', // We're attaching these fields to every product
fields: [
{
id: 'ingredients', // The field's object key
label: 'Ingredient list', // The label shown in the dashboard
type: 'collection',
fields: [
{
id: 'name',
label: 'Ingredient name',
type: 'short_text'
},
{
id: 'description',
label: 'Description',
type: 'long_text'
}
]
}
]
})
// Add some ingredient data to an existing product with the slug 'elderflower-tonic'
await swell.put('/:content', {
id: 'elderberry-tonic',
'content.ingredients': [
{
name: 'Organic Elderflower',
description: 'Picked by hand in the Swiss Alps.'
},
{
name: 'Grapefruit peel',
description: 'Aromatic but not too tart.',
},
{
name: 'Cane sugar',
description: 'Just enough to balance out the grapefruit.'
},
{
name: 'Quinine',
description: 'The real stuff, direct from farmers in Congo'
}
]
})
// Fetch the newly-updated product with our ingredient list
const product = await swell.get('/products/elderflower-tonic')
Within an existing data model
Using the ID of a data model will attach the content model to it. The fields of the content model become available on all entries in that collection.
Let's say we're an upscale beverage maker and want to have a list of ingredients for one of our fine tipples. Defining a content type with an ingredients field and collection: 'products' stores the data on a product object at product.content.ingredients.
We want each ingredient to have a name and description, so we'll use a collection field to allow any number of ingredients with those two fields to be added. Collection fields can accommodate other content types using the item_types attribute and passing an array of content type IDs, or define a set of fields that each item in the collection will have. Some CMS call this a 'repeated field'.
// Create the content type
await swell.put('/:content', {
name: 'Product details', // The name shown in the dashboard
description: 'Additional info about the product', // An optional description to help admins understand what this content type is for
collection: 'products', // We're attaching these fields to every product
fields: [
{
id: 'ingredients', // The field's object key
label: 'Ingredient list', // The label shown in the dashboard
type: 'collection',
fields: [
{
id: 'name',
label: 'Ingredient name',
type: 'short_text'
},
{
id: 'description',
label: 'Description',
type: 'long_text'
}
]
}
]
})
// Add some ingredient data to an existing product with the slug 'elderflower-tonic'
await swell.put('/:content', {
id: 'elderberry-tonic',
'content.ingredients': [
{
name: 'Organic Elderflower',
description: 'Picked by hand in the Swiss Alps.'
},
{
name: 'Grapefruit peel',
description: 'Aromatic but not too tart.',
},
{
name: 'Cane sugar',
description: 'Just enough to balance out the grapefruit.'
},
{
name: 'Quinine',
description: 'The real stuff, direct from farmers in Congo'
}
]
})
// Fetch the newly-updated product with our ingredient list
const product = await swell.get('/products/elderflower-tonic')
As abstract
Omitting the collection attribute makes the model abstract, meaning there's no collection or API endpoint where entries can be fetched directly. This is ideal for defining smaller groups of fields that are used within other content models, without polluting the global schema—making sets of fields reusable in multiple places makes the job of content editors and developers much simpler—resulting in more consistent structures.
Fields are a powerful way to shape structured content and define appropriate input components for admins. A field's type and ui property can be specified to determine the most appropriate formatting and editing experience from within the dashboard. If omitted or unspecified, the field type's relative default UI will be used.
Take the boolean field type for example:
// Boolean type defaults to a checkbox UI
{
id: ...,
label: ...,
type: 'boolean',
}
// Specify a boolean field with a toggle UI
{
id: ...,
label: ...,
type: 'boolean',
ui: 'toggle', //
}
Being able to create native-level data models and add to existing ones provides the opportunity to make your store work exactly how you need it to. Swell's recommended approach to customize data models directly is by configurations in Swell Apps.
You can view your store’s schema in the Swell dashboard, and through API endpoints such as the following.
GET /:models
To retrieve a single model, append the model’s ID:
GET /:models/products
That will return a result like this:
{
"version": "1.0.147",
"name": "products",
"api": "com",
"label": "Products",
"fields": {
"id": {
"type": "objectid"
},
"date_created": {
"type": "date",
"auto": true
},
"date_updated": {
"type": "date",
"auto": "update"
},
"name": {
"type": "string",
"required": true,
"localized": true
},
"slug": {
"type": "string",
"unique": true,
"required": true,
"format": "slug",
"default": {
"$formula": "slug(name)"
}
},
"sku": {
"type": "string",
"unique": true,
"label": "SKU"
},
"active": {
"type": "bool",
"default": false
},
"discontinued": {
"type": "bool"
},
"tags": {
"type": "array",
"value_type": "string"
},
"popularity": {
"type": "int"
},
"price": {
"type": "currency",
"localized": true,
"default": 0
},
"sale": {
"type": "bool"
},
"sale_price": {
"type": "currency",
"localized": true
},
...
}
}
Swell's data and content models provide unrestricted creative freedom. They are also scalable and can grow with your business needs.