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
extends:
  - Section
...
fields:
  - type: string
    name: title
    label: Title
  ...

Properties

type

name

  • 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.

label

  • 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.

required

  • 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.

default

  • 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.

const

  • 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.

hidden

  • 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.

string

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.

text

Use this type for multi-line plain text fields

markdown

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.

number

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 fields which have a defined minimum and maximum can be represented in the UI as a slider control.

boolean

A field holding either boolean true or false.

image

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.

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

datetime

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

date

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

color

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.

enum

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.
fields:
  # enum with a simple list of values
  - type: enum
    name: tag
    options: [foo, bar, baz]
  # enum with list of objects
  - type: enum
    name: element
    options:
      - label: 'Foo!'
        value: foo
      - label: My Bar
        value: bar
      - label: bazzz
        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. For more, see Field Editor Controls.

reference

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.

Consider this snippet from the blog post model:

name: PostLayout
label: Post
...
fields:
  ...
  - type: reference
    name: author
    models:
      - 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.

model

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.

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

name: PostLayout
label: Post
...
- type: model
    name: featuredImage
    label: Featured image
    models:
      - 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.

list

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:

# ...
fields:
  - type: list
    name: tags
    items:
      type: string
  - type: list
    name: sections
    items:
      type: model
      groups:
        - 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.

styles

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