Field types
How CMS field types map to Liquid objects in templates
This reference documents all field types available in block and template schema definitions. Field types define the input controls that appear in the CMS admin panel and determine how values are stored and accessed in Liquid templates.
Fields are defined in the settings array of a {% schema %} tag (for blocks and templates) or in config/settings_schema.json (for theme-level settings).
Common properties
All field types share these base properties:
| Property | Type | Required | Description |
|---|---|---|---|
type | String | Yes | The field type identifier (e.g., text, select, array) |
name | String | Yes | Unique field name. Used to access the value in templates. |
label | String | Yes | Human-readable label shown in the CMS admin panel |
required | Boolean | No | Whether the field must have a value. Default: false. |
defaultValue | Varies | No | Default value when no value is set by the editor |
deprecated | Boolean | No | Shows the field as deprecated in the admin while keeping existing values available |
Overview
| Field type | Category | Description | Template value type |
|---|---|---|---|
| text | Leaf | Single-line string input | String |
| textArea | Leaf | Multi-line string input | String |
| Leaf | Email input with validation | String | |
| url | Leaf | URL input with validation | String |
| number | Leaf | Numeric input | Number |
| checkbox | Leaf | Boolean true/false toggle | Boolean |
| switch | Leaf | Toggle switch (checkbox alias) | Boolean |
| color | Leaf | Colour picker | String (hex) |
| date | Leaf | Date picker | String (ISO date) |
| dateTime | Leaf | Date and time picker | String (ISO datetime) |
| radio | Leaf | Single selection from visible options | String |
| select | Leaf | Dropdown single selection | String |
| code | Leaf | Code editor input | String |
| json | Leaf | Raw JSON input | Object or Array |
| richText | Leaf | Rich text editor | Boolean + HTML string |
| hidden | Leaf | Hidden field (not visible in admin) | String |
| relationship | Relationship | Reference to another document | Object |
| upload | Relationship | File/media upload reference | Object |
| array | Container | Repeatable group of fields | Array of Objects |
| group | Container | Single group of fields | Object |
text
Category: Leaf Admin control: Single-line text input Template value: String
A single-line text input field.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "text" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | String | No | Default text value |
Schema example
{
"type": "text",
"name": "heading",
"label": "Heading",
"required": true,
"defaultValue": "Welcome"
}Template access
<h2>{{ block.heading }}</h2>textArea
Category: Leaf Admin control: Multi-line text input Template value: String
A multi-line text input field for longer text content. Does not support formatting -- use richText for formatted content.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "textArea" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | String | No | Default text value |
Schema example
{
"type": "textArea",
"name": "summary",
"label": "Summary text",
"required": false,
"defaultValue": ""
}Template access
{% if block.summary != blank %}
<p class="summary">{{ block.summary }}</p>
{% endif %}Note: The type name is camelCase: textArea, not textarea. The validator normalises textarea to textArea but the canonical form is camelCase.
Category: Leaf Admin control: Email input with format validation Template value: String
An email address input. The CMS validates that the value is a properly formatted email address.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "email" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | String | No | Default email value |
Schema example
{
"type": "email",
"name": "contact_email",
"label": "Contact email address",
"required": true
}Template access
<a href="mailto:{{ block.contact_email }}">{{ block.contact_email }}</a>url
Category: Leaf Admin control: URL input with format validation Template value: String
A URL input. The CMS validates that the value is a properly formatted URL.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "url" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | String | No | Default URL value |
Schema example
{
"type": "url",
"name": "external_link",
"label": "External link URL"
}Template access
{% if block.external_link != blank %}
<a href="{{ block.external_link }}" target="_blank" rel="noopener">Learn more</a>
{% endif %}number
Category: Leaf Admin control: Numeric input Template value: Number
A numeric input field for integer or decimal values.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "number" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | Number | No | Default numeric value |
Schema example
{
"type": "number",
"name": "columns",
"label": "Number of columns",
"defaultValue": 3
}Template access
<div class="grid grid--{{ block.columns }}-col">
{% for item in block.items %}
<div class="grid__item">{{ item.title }}</div>
{% endfor %}
</div>checkbox
Category: Leaf
Admin control: Checkbox toggle
Template value: Boolean (true or false)
A boolean toggle rendered as a checkbox in the admin panel.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "checkbox" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | Boolean | No | Default state (true or false) |
Schema example
{
"type": "checkbox",
"name": "show_background",
"label": "Show background colour",
"defaultValue": false
}Template access
{% if block.show_background %}
<section class="section section--with-bg" style="background-color: {{ block.background_color }};">
{% else %}
<section class="section">
{% endif %}switch
Category: Leaf
Admin control: Toggle switch
Template value: Boolean (true or false)
A boolean toggle rendered as a switch in the admin panel. Functionally identical to checkbox but with a different visual presentation.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "switch" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | Boolean | No | Default state (true or false) |
Schema example
{
"type": "switch",
"name": "enable_animation",
"label": "Enable entrance animation",
"defaultValue": true
}Template access
<div class="hero{% if block.enable_animation %} hero--animated{% endif %}">
...
</div>See also
color
Category: Leaf Admin control: Colour picker Template value: String (hex colour code)
A colour picker that returns a hex colour string (e.g., #ff5733).
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "color" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | String | No | Default hex colour value |
Schema example
{
"type": "color",
"name": "accent_color",
"label": "Accent colour",
"defaultValue": "#e94560"
}Template access
<section style="border-left: 4px solid {{ block.accent_color }};">
{{ block.content_html }}
</section>date
Category: Leaf Admin control: Date picker Template value: String (ISO date format)
A date picker without time component.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "date" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | String | No | Default date in ISO format |
Schema example
{
"type": "date",
"name": "publish_date",
"label": "Publish date"
}Template access
{% if block.publish_date != blank %}
<time datetime="{{ block.publish_date }}">
{{ block.publish_date | date: "%d %B %Y" }}
</time>
{% endif %}dateTime
Category: Leaf Admin control: Date and time picker Template value: String (ISO datetime format)
A date and time picker.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "dateTime" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | String | No | Default datetime in ISO format |
Schema example
{
"type": "dateTime",
"name": "event_start",
"label": "Event start time"
}Template access
<time datetime="{{ block.event_start }}">
{{ block.event_start | date: "%d %B %Y at %H:%M" }}
</time>Note: The type name is camelCase: dateTime, not datetime. The validator normalises datetime to dateTime but the canonical form is camelCase.
radio
Category: Leaf
Admin control: Radio button group
Template value: String (the selected option's value)
A single-selection field rendered as visible radio buttons. Use when there are few options and visibility of all choices is helpful.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "radio" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | String | No | Default selected value |
options | Array | Yes | Array of { label, value } objects |
Schema example
{
"type": "radio",
"name": "text_alignment",
"label": "Text alignment",
"options": [
{ "label": "Left", "value": "left" },
{ "label": "Centre", "value": "center" },
{ "label": "Right", "value": "right" }
],
"defaultValue": "left"
}Template access
<div class="text-block text-block--align-{{ block.text_alignment }}">
{{ block.body_html }}
</div>See also
select
Category: Leaf
Admin control: Dropdown select
Template value: String (the selected option's value)
A single-selection dropdown field. Use when there are many options or screen space is limited.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "select" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | String | No | Default selected value |
options | Array | Yes | Array of { label, value } objects |
Schema example
{
"type": "select",
"name": "layout_variant",
"label": "Layout variant",
"options": [
{ "label": "Full width", "value": "full-width" },
{ "label": "Contained", "value": "contained" },
{ "label": "Narrow", "value": "narrow" },
{ "label": "Split", "value": "split" }
],
"defaultValue": "contained"
}Template access
<section class="section section--{{ block.layout_variant }}">
{{ block.content_html }}
</section>See also
code
Category: Leaf Admin control: Code editor Template value: String
A code editor input with syntax highlighting. Suitable for embed codes, custom scripts, or structured data.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "code" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | String | No | Default code value |
Schema example
{
"type": "code",
"name": "embed_code",
"label": "Embed code"
}Template access
{% if block.embed_code != blank %}
<div class="embed-wrapper">
{{ block.embed_code }}
</div>
{% endif %}json
Category: Leaf Admin control: JSON editor Template value: Object or Array (parsed JSON)
A raw JSON input field. The value is stored and returned as a parsed JSON structure.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "json" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | Object or Array | No | Default JSON value |
Schema example
{
"type": "json",
"name": "chart_data",
"label": "Chart data (JSON)",
"defaultValue": { "labels": [], "values": [] }
}Template access
{% if block.chart_data %}
<div class="chart" data-config='{{ block.chart_data | json }}'>
</div>
{% endif %}richText
Category: Leaf Admin control: Rich text editor (the rich text editor) Template value: Boolean (field presence) + String (HTML)
A rich text editor powered by the rich text editor. Rich text fields are flattened into two template properties:
field_name-- Boolean indicating whether the field has content (trueif content exists)field_name_html-- The rendered HTML string
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "richText" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
defaultValue | Object | No | Default the rich text editor editor state |
Schema example
{
"type": "richText",
"name": "body",
"label": "Body content",
"required": true
}Template access
{% if block.body %}
<div class="rich-text">
{{ block.body_html }}
</div>
{% endif %}The boolean property (block.body) is useful for conditional rendering -- check it before outputting the HTML. The HTML property (block.body_html) contains the fully rendered markup.
Note: The type name is camelCase: richText, not richtext. The validator normalises richtext to richText but the canonical form is camelCase.
hidden
Category: Leaf Admin control: None (not visible in admin panel) Template value: String
A hidden field that stores a value without displaying an input control in the admin panel. Useful for internal identifiers or machine-readable metadata.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "hidden" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label (used internally, not shown to editors) |
required | Boolean | No | Whether a value is required |
defaultValue | String | No | Default value |
Schema example
{
"type": "hidden",
"name": "block_version",
"label": "Block version",
"defaultValue": "2.0"
}Template access
<div data-version="{{ block.block_version }}">
...
</div>relationship
Category: Relationship Admin control: Document selector Template value: Object (the related document, flattened)
A reference to another document in the CMS. The related document is resolved and its data is available as a nested object. Relationship values are automatically unwrapped and flattened, with a __collection hint added.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "relationship" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
relationTo | String | Yes | The collection slug to relate to (e.g., pages, events, people, venues) |
Schema example
{
"type": "relationship",
"name": "featured_event",
"label": "Featured event",
"relationTo": "events"
}Template access
{% if block.featured_event %}
<div class="featured-event">
<h3>{{ block.featured_event.title }}</h3>
{% if block.featured_event.image %}
<img src="{{ block.featured_event.image | image_url: width: 600 }}" alt="{{ block.featured_event.image.alt }}">
{% endif %}
<a href="{{ block.featured_event.url }}">View event</a>
</div>
{% endif %}The related document object contains all its published fields (title, slug, image, url, etc.) as resolved properties.
upload
Category: Relationship Admin control: File upload / media selector Template value: Object (the media document)
A file or media upload reference. By default, relates to the media collection. The uploaded file's data (URL, dimensions, alt text) is available as a nested object.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "upload" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether a value is required |
relationTo | String | No | The collection slug for uploads. Defaults to media. |
Schema example
{
"type": "upload",
"name": "background_image",
"label": "Background image"
}With explicit collection:
{
"type": "upload",
"name": "programme_pdf",
"label": "Programme PDF",
"relationTo": "media"
}Template access
{% if block.background_image %}
<div
class="hero-bg"
style="background-image: url('{{ block.background_image | image_url: width: 1920 }}');"
>
<h2>{{ block.heading }}</h2>
</div>
{% endif %}For file downloads:
{% if block.programme_pdf %}
<a href="{{ block.programme_pdf | file_url }}" download>
Download Programme ({{ block.programme_pdf.filename }})
</a>
{% endif %}The media object includes properties like url, filename, alt, width, height, mimeType, and sizes (for predefined image variants).
array
Category: Container Admin control: Repeatable field group with add/remove/reorder controls Template value: Array of Objects
A repeatable group of fields. Each row contains a set of sub-fields and receives a unique ID. Use for lists of items like slides, features, testimonials, or links.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "array" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
required | Boolean | No | Whether the array must have at least one row |
fields | Array | Yes | Array of field definitions for each row |
Schema example
{
"type": "array",
"name": "slides",
"label": "Slides",
"fields": [
{
"type": "upload",
"name": "image",
"label": "Slide image",
"required": true
},
{
"type": "text",
"name": "caption",
"label": "Caption"
},
{
"type": "url",
"name": "link",
"label": "Link URL"
}
]
}Template access
{% if block.slides.size > 0 %}
<div class="slider">
{% for slide in block.slides %}
<div class="slider__slide">
<img src="{{ slide.image | image_url: width: 1200 }}" alt="{{ slide.caption | default: '' }}">
{% if slide.caption != blank %}
<p class="slider__caption">{{ slide.caption }}</p>
{% endif %}
{% if slide.link != blank %}
<a href="{{ slide.link }}" class="slider__link">Learn more</a>
{% endif %}
</div>
{% endfor %}
</div>
{% endif %}Each row in the array is an object with the sub-field values as properties. Sub-fields follow the same rules as top-level fields -- rich text fields are flattened into _html pairs, relationships are unwrapped, and so on.
The recommended maximum nesting depth for arrays and groups is 4 levels. Deeper nesting triggers a validation warning.
group
Category: Container Admin control: Collapsible field group Template value: Object
A single group of fields. Unlike array, a group is not repeatable -- it contains exactly one set of sub-fields. Use for logically related fields that should be visually grouped in the admin panel.
Properties
| Property | Type | Required | Description |
|---|---|---|---|
type | "group" | Yes | Field type identifier |
name | String | Yes | Field name |
label | String | Yes | Display label |
fields | Array | Yes | Array of field definitions within the group |
Schema example
{
"type": "group",
"name": "cta",
"label": "Call to action",
"fields": [
{
"type": "text",
"name": "button_text",
"label": "Button text",
"defaultValue": "Learn more"
},
{
"type": "url",
"name": "button_url",
"label": "Button URL",
"required": true
},
{
"type": "select",
"name": "button_style",
"label": "Button style",
"options": [
{ "label": "Primary", "value": "primary" },
{ "label": "Secondary", "value": "secondary" },
{ "label": "Outline", "value": "outline" }
],
"defaultValue": "primary"
}
]
}Template access
{% if block.cta.button_url != blank %}
<a href="{{ block.cta.button_url }}" class="btn btn--{{ block.cta.button_style }}">
{{ block.cta.button_text | default: "Learn more" }}
</a>
{% endif %}Group properties are accessed using dot notation: block.group_name.field_name. Groups can contain any field type, including nested arrays or groups (up to the recommended maximum depth of 4).
Index
By name
- array -- repeatable group of fields
- checkbox -- boolean toggle
- code -- code editor input
- color -- colour picker
- date -- date picker
- dateTime -- date and time picker
- email -- email input with validation
- group -- single group of fields
- hidden -- hidden field
- json -- raw JSON input
- number -- numeric input
- radio -- single selection from radio buttons
- relationship -- reference to another document
- richText -- rich text editor
- select -- dropdown single selection
- switch -- toggle switch
- text -- single-line text input
- textArea -- multi-line text input
- upload -- file/media upload reference
- url -- URL input with validation
By category
Leaf types
- text
- textArea
- url
- number
- checkbox
- switch
- color
- date
- dateTime
- radio
- select
- code
- json
- richText
- hidden
Relationship types
Container types
Related
- Liquid tags reference -- the schema tag for defining block and template schemas
- Liquid filters reference -- filters for working with field values in templates
- How to create custom blocks -- using field types in block schemas
- How to create page templates -- using field types in template schemas
- How to define theme-level settings -- using field types in settings_schema.json