Jump into customizing Swell's models and start building on Swell.

Each Swell store has an editable schema based on models. These are the building blocks that shape each store and house both content, data, and store logic. 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.

With great power comes great responsibility. There are no restrictions when working with models, and you have complete freedom to shape them how you please.

Models are accessible via API and can also be customized from within the Swell dashboard under Developer > Models. To begin customizing your models via API, you’ll need to authenticate your store:

Authentication
$ curl https://client_id:client_key@api.swell.store

Swell comes with a suite of standard ecommerce models and 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.

You can access your store’s schema through the following endpoint:

GET method
GET /:models

To retrieve a single model, append the model’s ID:

Retrieve a single model
GET /:models/products

That will return a result like this:

The product model
// The product model

{
  "version": "1.0.147",
  "name": "products",
  "api": "com",
  "label": "Product",
  "plural": "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)"
      }
    },
    "type": {
      "type": "string"
    },
    "sku": {
      "type": "string",
      "unique": true,
      "label": "SKU"
    },
    "code": {
      "type": "string",
      "label": "Barcode",
      "description": "Product barcode, UPC, EAN, or ISBN"
    },
    "active": {
      "type": "bool",
      "default": false
    },
    "demo": {
      "type": "bool"
    },
    "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
    },
    "compare_price": {
      "type": "currency",
      "localized": true
    },
    "cost": {
      "type": "currency"
    },
    {. . .},
   }
  }

Imagine we’re building out a store for a specialty coffee roaster. For each coffee, we want to show details like the region it was grown, the varietal, tasting notes, and the producer.

Since we want to display our custom content alongside commerce data like pricing and options, we’ll add some custom fields to the standard product model:

  • The varietal could be basically anything, so we’ll use a short text field.
  • The tasting notes are equally open-ended, so we’ll use a short text field for those, too.
  • However, we want to have content about each producer, so we’ll create a new collection for modeling them so that the collection can be referenced from the product.
  • Since our roaster only works with single-farm producers, we can store region as part of the producer entries to avoid repeated entries. That also makes it possible to filter coffees by producer or region if we want to later on.

Here’s what that request would look like:

Customizing the product model
// Add our custom fields to the standard product model

swell.post('/:content', {
  collection: 'products', // ID of the model to attach the fields to
  description: 'Coffee details', // A way to identify the field set
  fields: [
    {
      id: 'varietal',
      label: 'Varietal',
      type: 'short_text',
      max: 100, // Limit value to 100 characters
    },
    {
      id: 'tasting_notes',
      label: 'Tasting notes',
      type: 'short_text',
      max: 150, // Limit value to 150 characters
    },
    {
      id: 'producer',
      label: 'Producer',
      type: 'lookup',
      collection: 'content/producers',
    },
  ],
});

Using the content namespace means fields will be available in the Frontend API. This is ideal for information intended for public display.

Since the information about producers is not used for business logic and is intended for public display, we’ll create a content model to store it. These models can be visualized in the model explorer and edited in the dashboard. For this new model:

  • The name is the entry title, so we’ll use a short text field.
  • We want a slug to use as a more human-friendly ID in URLs, and this should be derived from the name field. It also needs to be unique.
  • For region, we’ll use a short text field.
  • The bio is longer form and might have links or additional formatting, so we’ll use a long text field.

Here’s the request to create our new model:

Creating a custom content model
// Create a custom producers model

swell.post('/:content', {
  collection: 'content/producers',
  name: 'Producers',
  description: 'Producer details',
  fields: [
    {
      id: 'name',
      label: 'Name',
      type: 'short_text',
      required: true, // Require value before saving entry
    },
    {
      id: 'slug',
      label: 'Slug',
      type: 'short_text',
      ui: 'slug',
      unique: true, // Ensure value is unique within collection
      required: true, // Require value before saving entry
      default: {
        $formula: 'slug(name)', // Default to slugified name
      },
    },
    {
      id: 'region',
      label: 'Region',
      type: 'short_text',
      max: 100, // Limit value to 100 characters
    },
    {
      id: 'bio',
      label: 'Bio',
      type: 'long_text',
      max: 500, // Limit value to 500 characters
    },
  ],
});

By exploring model customization, you are able to expand upon Swell’s core functionality and fine-tune your store experience. Now that we’ve covered customizing models, we recommend exploring our data types to learn about modeling data types while working with your store’s models.

If you’d like a deep dive into customizing data models, be sure to check out our conceptual guide: Data model customization.