Models describe your site's content structure. Models are defined inside the models
property if the stackbit.yaml
. The models
is an object where its keys represent the model names and values are the model definitions.
Model Types
Every model must belong to one of three types:
- Page Models (
type: page
) describe the pages of your site stored in markdown files (e.g..md
,.mdx
,.markdown
). - Data Models (
type: data
) describe the arbitrary data of your site stored in data files (e.g..yml
,.yaml
,.toml
,.json
). - Object Models (
type: object
) describe the objects that can be nested within other objects of Page and Data models.
Example (for simplicity, all model properties except type
were omitted):
models:
# a "post" model that describes pages (of type "post")
# that could be stored in .md files
post:
type: page
# ... other properties
# an "author" model that describes an objects (of type "author")
# that could be stored in .json files (one per author)
author:
type: data
# ... other properties
# an "action" model that describes an object (of type "action")
# that could be stored within other pages or objects
action:
type: object
# ... other properties
type: page
) and their urlPath
.
Choosing a model type
Page
Choose page when each data record will be stored in a standalone file and will correspond to a unique URL on your web site.
Data
Choose data for standalone data files that do not correspond to URLs on your site.
Object
Objects are useful when you need to define a complex data model, but standalone files (e.g. home-hero.json
, about-hero.json
, and contact-hero.json
page sections) could clutter the content authoring experience.
Tip: You can nest any of the three model types inside another.
Model Naming Rules
As shown in the previous example, models are named as keys within the YAML file and must adhere to the following rules:
- Must start with and end with a letter
- Can contain only lower case alphanumeric characters or underscores
_
Common Model Properties
type
- Allowed values:
page
,data
,object
- Required: true
The type of the model.
Example
models:
home:
type: page
# ... other properties
label
- Allowed values: string
- Required: true
A short, descriptive name for the model. For example if you were creating a page model for a blog page you might use the label "Blog" but you could also use "Article". The model label is displayed besides the name of the content item.
Example
models:
home:
type: page
label: "Blog Post"
description
- Allowed values: string
- Required: false
Description of the model.
Example
models:
home:
type: page
label: "Blog Post"
description: "Create a new blog post"
fields
- Allowed values: list of Fields
- Required: true (forbidden for
data
models withisList: true
)
The fields that that make up the data within the model.
Example
models:
home:
type: page
label: "Blog Post"
description: "Create a new blog post"
fields:
- type: string # the type of the model field
name: title # the name of the field
label: Title
Model Matching Properties
Model matching properties are applicable to Page Models and Data Models only. They are used to match the models
defined in stackbit.yaml
to content files these models represent. When Stackbit loads your content files, it needs to know which files belong to which models. The process that matches models to content files is called Model Matching. To let Stackbit do the model matching, your models should specify the "Model Matching Properties":
file
- matches a model to a single file relative topagesDir
forpage
models ordataDir
fordata
models. Default is undefined.layout
- matches a model to all pages having the same value in a field specified by thepageLayoutKey
. Applicable forpage
models only. Default is undefined.folder
- matches a model to all files inside a folder relative topagesDir
forpage
models ordataDir
fordata
models.match
- additional filter that matches file glob(s) relative to thefolder
. Default is all files**/*
exclude
- additional filter that excludes file glob(s) relative to thefolder
. Default is undefined.
To learn more about model matching properties visit Page Model Matching Properties or Data Models Matching Properties.
Every content file in your site within the pagesDir
or the dataDir
must match a single model. If a file matches multiple models you will get a validation error when running stackbit validate
CLI command.
You may use the global excludePages
to exclude files from being loaded and matched to any model.
Example
Assume your site has three types of pages represented by three page
models - index
, post
and project
. The post
and project
pages are located inside posts
and projects
folders respectively, and the index
pages can be located in any folder:
├── content
│ ├── index.md (model: index)
│ └── posts
│ │ ├── index.md (model: index)
│ │ ├── post-1.md (model: post)
│ │ └── post-2.md (model: post)
│ └── projects
│ ├── index.md (model: index)
│ ├── project-1.md (model: project)
│ └── project-2.md (model: project)
└── stackbit.yaml
pagesDir: content
models:
index:
type: page
label: Index
# match index.md file in any folder
match: "**/index.md"
# ... other properties
post:
type: page
label: Article
# match any files inside {pagesDir}/posts excluding index.md
folder: posts
exclude: index.md
# ... other properties
project:
type: page
label: Project
# match any files inside {pagesDir}/project excluding index.md
folder: project
exclude: index.md
# ... other properties
Examples
Project without a headless-CMS
Assume your site has several post files inside the content/posts
folder with two properties - title
and featured_image
, and another settings.yaml
file inside the data
folder:
├── content
│ └── posts
│ ├── post1.md
│ └── post2.md
├── data
│ └── settings.yaml
└── stackbit.yaml
To model your content you will need to define two models in your stackbit.yaml
. One model of type page
called post
representing your post pages and another model of type data
called settings
representing the settings.yaml file. Inside each of these models you will need to define several model properties describing your models and the fields
of your content files.
stackbitVersion: ~0.3.0
# ... ssgName, cmsName, etc.
pagesDir: content
dataDir: data
models:
# a model of type "page" called "post"
post:
type: page
label: Post
# this model matches all markdown files in the "content/posts" folder
folder: posts
# the urlPath defines the URL pattern for posts,
# the {slug} is extrapolated from filePath
# note the URL pattern is different from the physical folder path
urlPath: "/blog/{slug}"
# the filePath defines where new post files will be stored
# and used to extrapolate the {slug} for the urlPath
filePath: "/posts/{slug}.md"
# list of model fields
fields:
- type: string
name: title
label: Title
- type: image
name: featured_image
label: Featured Image
# a model of type "data" called "settings"
settings:
type: data
label: Settings
# this model matches a single "data/settings.yaml" file
file: settings.yaml
singleInstance: true
# list of model fields
fields:
- type: string
name: title
label: Sites Title
- type: image
name: logo
label: Logo Image
Project with a headless-CMS
As noted before, if your site is configured to work with an external headless-CMS, Stackbit will read the models from that CMS. Therefore, all you need to specify in stackbit.yaml
is the types of your models (i.e., type: page
, type: data
). If your content is file-based then you also need to specify the urlPath
and filePath
for your page models.
The name of the model in stackbit.yaml
must match the name of the model in the external CMS.
stackbitVersion: ~0.3.0
...
models:
home:
type: page
urlPath: "/"
page:
type: page
urlPath: "/{slug}"
post:
type: page
urlPath: "/blog/{slug}"
filePath: "/posts/{slug}.md"
author:
type: data