All fields declared by a model are listed as objects under the fields property.

The only mandatory properties of new fields are name and type. It is also common, though not required, to set a label.

Here's a short snippet demonstrating that:

name: HeroSection
  - Section
  - type: string
    name: title
    label: Title




  • Allowed values: a valid name
  • Required: Yes

The field name should follow these rules:

  • Contain only alphanumeric characters, underscores or hyphens.
  • Start with a letter.
  • Cannot end with an underscore or a hyphen.


  • Allowed values: string
  • Required: No
  • Default: If not defined, the label is set to the name with all initials capitalized.

This property denotes an optional human-friendly name that will be used in the UI. It can be changed without affecting stored data or other models.


  • Allowed values: true/false
  • Required: No
  • Default: false

If a field is required and left empty in a piece of content, publishing will result in an error message to the content editor.


  • Allowed values: The default value for this field that will be used when creating a new content piece
  • Required: No
  • Default: None

The Stackbit UI will set this value to the field when adding new content., e.g. adding a new page, adding a new component to an existing page.

Note: this is not a fallback value. if a field's value is empty when publishing the content, its value is not set back to default.


  • Allowed values: A constant value that should be used when the creating a new content piece
  • Required: No

If you need a specific value to always be set for any instance of this model, set const to that value. The UI will display that value as read-only and will not let the user change it. Do not define default in this case.

Why have const fields at all?

The need for constant values usually stems from the integration between the content model and the rendering code.

For example, you may want to have multiple models which are all compatible with the same rendering code, but the behavior of the code should change somewhat - depending on which model was actually passed.

In such a case, instead of the code switching its behavior depending on the content type, it's better if it bases its logic on a field value. Using const fields, you ensure that the appropriate value for the model is always set for all content items of a given type - while keeping the code cleaner and more maintainable.

If you don't want the field to be visible in the UI, also set hidden: true for that field.


  • Allowed values: true/false
  • Required: No
  • Default: false

If you're setting a fixed constant value for a field (see the const property above) and you don't want that field to be at all visible to content creators in the visual editor, set hidden to true.

Field Types

Here are all supported field types. The Stackbit UI provides a default editor control per each type, but the default control can be changed for some types.


Use this type for short single-line strings of plain text.

The editor UI does not support multiple lines or any formatting options for this type.


Use this type for multi-line plain text fields


Use for text that is to be rendered by components as Markdown.

The UI will show a rich text editor to the end user. When editing is finished, the edited text is transformed to Markdown syntax and stored as the field value.

Our components assume that field values are the passed as-is, so that transforming the Markdown syntax to JSX or pure HTML is the responsibility of the component itself. There are multiple libraries to perform this, either in vanilla JavaScript and some specifically for React. We use markdown-to-jsx.


A field which accepts numbers only.

This type supports additional properties which are all optional:

  • subtype: int (default) or float.
  • min and max
  • step to indicate that only a specific increment/decrement value is allowed.

Number Field Types

Numbers are input fields of type number by default, but have additional options for controls.


This control type can be used on numeric fields that have a fixed range. The min and max properties of numeric fields must be set for this control to function.

Slider Editor Control

You can also optionally define a step (the default is 1) and a unit denominator that will be displayed next the the current value. The unit has no effect on the actual stored value.

- type: number
  name: letterSpacing
  controlType: 'slider'
  min: 0
  max: 100
  step: 10
  unit: '%'

- type: number
  name: lineHeight
  controlType: 'slider'
  min: 100
  max: 200
  step: 20
  unit: 'px'


A field holding either boolean true or false.


The path to the image file. The Stackbit UI will let the content creator choose an existing image or upload a new one, according to your asset settings.

- type: image
  name: avatar

After an image has been selected in the UI, the path to it will be set according to asset configuration (relative or static).

Cloudinary Integration

Image fields support our Cloudinary integration. When the integration is properly configured, image fields will automatically support Cloudinary as the source.

However, by default, only the secure_url of that asset is stored.

# Only the path to the image is stored
- type: image
  name: avatar

This allows content editors to freely toggle between selecting images from Cloudinary and choosing from image files in the repository.

Storing Image Metadata

When using the Cloudinary integration, you can choose to store the full image metadata from Cloudinary. Add source: cloudinary as a property to the field's definition.

# Full image metadata is stored, and
# only Cloudinary images may be selected
- type: image
  name: headshot
  source: cloudinary

For fields configured in this way, using git-based assets is disabled. Only Cloudinary images can be selected.


A date and time field.

The field value is stored in ISO-8601 format, in second resolution and with timezone, e.g. 2017-03-09T14:25:52-05:00


A field holding a date only, with no time.

The field value is stored in date-only ISO-8601 format, e.g. 2017-03-09


A field holding a color in hex format, e.g.: #ff0000. The content editor will be presented with a color picker component to edit this field type.

When setting a default value for this field, you can either use a hard-coded hex value (e.g. '#f5f5f5'), or the '${name}' syntax to refer to a named color in your project's Tailwind configuration file.

For example, given the colors configured here you can use values such as $primary or $light.

When using the $ syntax for default values, color names are replaced by their actual hex value when new content pieces are created (i.e. new pages or nested components). This substitution is transparent to your components' code.


The enum type requires specifying an options attribute with list of allowed values.

That list can be either:

  1. A list of strings. This is represented in YAML with the shorthand notation [a, b, c] - see below.
  2. List of objects with label and value attributes: the label specifies the string displayed in the editor UI, while the value specifies the actual value stored in the field.
  # enum with a simple list of values
  - type: enum
    name: tag
    options: [foo, bar, baz]
  # enum with list of objects
  - type: enum
    name: element
      - label: 'Foo!'
        value: foo
      - label: My Bar
        value: bar
      - label: baz
        value: baz

Note: by default, the UI will use a simple dropdown control for editing enum fields.

However, you can use other editor controls where applicable, such as a button group or a list of thumbnails. See below for more detail.

Enum Control Types

dropdown (default)

This is the default control for the enum field type. It shows a simple drop-down list of options.

- type: enum
  name: colorStyle
  controlType: 'dropdown'
    - label: Primary Color
      value: primary
    - label: Secondary Color
      value: secondary

Useful for a short list of options that doesn't require a dropdown

Button Group Editor Control

- type: enum
  name: width
  label: Width
  group: design
  controlType: button-group
    - label: Narrow
      value: narrow
    - label: Wide
      value: wide
    - label: Full
      value: full

This control is useful for selecting between options that can benefit from having a visual representation for each, e.g. different visual layouts for a component.

To define the images, set the thumbnail property for each item. The file path should be relative to the project root (these images are not published as public assets during the build, they are only used in the editor UI).

Here's an imaginary model using this control type:

name: FlexibleSection
# ...
  - type: enum
    name: visualLayout
    label: Layout
    controlType: 'thumbnails'
      - value: content-left
        label: Content on left, image on right
        thumbnail: './images/content-left.png'
      - value: content-right
        label: Content on right, image on left
        thumbnail: './images/content-right.png'
      - value: content-top
        label: Content on top, image at bottom
        thumbnail: './images/content-top.png'

This control is useful for selecting color schemes for components from several fixed options.

This is a simpler alternative to using a thumbnails control. Rather than requiring you to create thumbnails, it lets you define items which mock each color scheme. Each item is rendered in the UI as a tile with specific colors for its background, text and border.

Here's how the control might look like in the UI:

Palette Editor Control

As with any enum field, once a user selects any of the options it is the value of that option that is set as the field value. This value is always a string. In the example below, these values are: "style-a", "style-b", and so on. It is then the rendering component's responsibility to apply that named style.

The control adds the following properties to the options object to set the appearance of tiles:

  • textColor
  • backgroundColor
  • borderColor - if not specified, no border will be drawn.
- type: enum
  name: look
  controlType: 'palette'
    - value: style-a
      textColor: '#FFFFFF'
      backgroundColor: '#000000'
    - value: style-b
      textColor: '#000000'
      backgroundColor: '...'
      borderColor: '#000000'
    # ...and so on
As with fields of type color, you can use named colors instead of fixed hex values.


Fields of type reference store a link to another stand-alone content item. In programming languages, this is akin to the concept of holding an object by reference. The referenced item must be of type page or data.

Consider this snippet from the blog post model:

name: PostLayout
label: Post
  - type: reference
    name: author
      - Person

This model has a reference field to the post's author, which must be a model of type Person (for example). The user wants to link each post to any of the existing Person instances, rather than have multiple duplicates of the same person embedded in all posts by the same author.

Assuming that the component rendering the blog also renders the author's details as part of it work, then modifying fields in the referenced Person will affect any linked post. In this case, that's exactly what we want.

Specifying acceptable model types

A reference field can accept more than one model type. You can either:

  1. Define a list of one or more model names with the models attribute - as in the snippet above
  2. or, list one or more model groups with the groups attribute. In this case, the field will accept any model that is currently defined as a member in any of these groups.

In both cases, if more than one concrete model type is accepted, the UI will allow the user to select the desired type, e.g. which type of section to append to a page.

See also: the model field below.


Fields of type model are used to store nested objects that are fully embedded within their parent. In programming languages, this is akin to the holding an object by value. Models used here must be of the object type — page and data models should not be used.

Here's a snippet from the built-in blog post model:

name: PostLayout
label: Post
- type: model
    name: featuredImage
    label: Featured image
      - ImageBlock

Each blog post can have a featured image, which links to an image file, has a caption and a few other settings. These settings are defined by the model ImageBlock(example(), so that the same definition can be reused under multiple models. However, the actual values for the ImageBlock (i.e. the instance of that model) are always stored within the parent content.

The data of the featured image is not saved as a separate file, but rather included within its parent - in this case, a blog post.

Specifying acceptable model types

Similar to the reference field type, you can define either a list of one or more model names via the models property, or a list of model groups via the groups property.


Similar to the model field type, but used for nested objects that are not represented by another model.

name: PostLayout
label: Post
# ...
  - type: object
    name: nestedObject
    label: Nested Object
      - type: string
        name: title
        required: true


A field of type list represents a lists of items of a specified type. That type could be any of the valid field types (which are listed above in this article).

To define the type, set items.type as below:

# ...
  - type: list
    name: tags
      type: string
  - type: list
    name: sections
      type: model
        - sectionComponent

If type is omitted, the type is set to string by default.

Some item types require additional attributes. These are defined similarly for both the "single item" field and for the list fields with the same type:

  1. List fields with items of type model and reference should define either a list of one or more models or one or more groups (as in the example above). This is similar to single-item fields or type model and reference.
  2. For list of item type enum, define the allowed values under items.options, with the same syntax as in the enum type.

List Control Types

List controls are based on the type of the provided options.


Lists can be represented as checkboxes when the options are of type enum. This is useful for controlling the options available for a list of strings.

Checkbox field control

- type: list
  name: categories
  controlType: checkbox
    type: enum
      - 'Category #1'
      - 'Category #2'
      # ...


  • Allowed values: URL-friendly characters
  • Required: No

The slug property on a page is often used to help determine the full URL path to a page (set by the urlPath property on the model), though any page properties can be used to generate URLs.

Aside from file-based content sources (see below), slug fields are inferred automatically by Stackbit based on the content source's schema. Fields cannot be converted to slugs.

Slug Behavior for File-Based Content

When content is stored in files (Git CMS), the slug is the path to the file relative to pagesDir, excluding the file extension.

For example, if a content file is stored at the path content/pages/, and urlPath is left to the default /slug, the page will be mapped to the URL /about .

This behavior cannot be adjusted at this time. It is recommended to use the default slug behavior provided by Stackbit when storing content in files.

Changing a Slug Property

When a slug field can be inferred from an API-based content source, changing it in Stackbit will result in a warning dialog.

Warning when changing a slug

After confirming this is the desired behavior, the editor will be redirected to a new page.

Slug change underway feedback

This behavior does not apply to file-based content. Nor does the warning or redirect occur when the change is made in the content source. Learn more about changing a page's URL.


For information on the styles field type and its specification, see here.