Block schema reference
Every field type and property available in block schemas — text, lists, dates, relationships, uploads, groups, arrays
Reference for the JSON schema format used in {% schema %} tags inside blocks/*.liquid. The same field types are used in template schemas (templates/*.liquid).
This reference covers {% schema %} in block and template files, which list their fields in a settings array and set field defaults with defaultValue. Global theme settings in config/settings_schema.json use a different structure — groups with a fields array, and field defaults set with default. The field types below apply to both. See Theme settings for the global settings structure.
Top-level properties
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
name | string | Yes | — | Unique identifier across all blocks in the theme |
settings | array | Yes | — | Array of field definition objects |
singular | string | No | Value of name | Singular display label in the admin |
plural | string | No | Value of name | Plural display label in the admin |
label | string | No | Value of name | Short admin label |
{
"name": "hero-banner",
"singular": "Hero Banner",
"plural": "Hero Banners",
"label": "Hero Banner",
"settings": []
}Common field properties
Every field in settings supports these:
| Property | Type | Required | Default | Description |
|---|---|---|---|---|
type | string | Yes | — | Field type. See below. |
name | string | Yes | — | Unique field name within this block. Accessed in Liquid as block.[name]. |
label | string | No | — | Human-readable label in the admin |
required | boolean | No | false | Whether the field must be filled in |
defaultValue | mixed | No | — | Default value when empty. Type must match the field type. |
deprecated | boolean | No | false | Marks the field as deprecated in the admin while keeping existing values available. |
{
"type": "text",
"name": "heading",
"label": "Section heading",
"required": true,
"defaultValue": "Welcome",
"deprecated": true
}Field types
text
Single-line text input. Liquid type: string.
{ "type": "text", "name": "title", "label": "Title", "defaultValue": "Untitled" }{{ block.title }}textArea
Multi-line text input. Also accepted as textarea (normalised). Liquid type: string.
{ "type": "textArea", "name": "summary", "label": "Summary" }email
Email address input. Liquid type: string.
{ "type": "email", "name": "contact_email", "label": "Contact email" }url
URL input. Liquid type: string.
{ "type": "url", "name": "link", "label": "Link URL" }number
Numeric input. Liquid type: number.
{ "type": "number", "name": "columns", "label": "Number of columns", "defaultValue": 3 }checkbox
Boolean toggle rendered as a checkbox. Liquid type: boolean.
{ "type": "checkbox", "name": "show_border", "label": "Show border", "defaultValue": false }switch
Boolean toggle rendered as a switch. Functionally identical to checkbox. Liquid type: boolean.
color
Colour picker. Liquid type: string (hex value).
{ "type": "color", "name": "accent_colour", "label": "Accent colour", "defaultValue": "#2563eb" }date
Date picker (date only). Liquid type: string (ISO date).
{ "type": "date", "name": "start_date", "label": "Start date" }<time datetime="{{ block.start_date }}">{{ block.start_date | date: '%d %B %Y' }}</time>dateTime
Date and time picker. Also accepted as datetime (normalised). Liquid type: string (ISO datetime).
radio
Radio button group for single selection.
| Property | Type | Required | Description |
|---|---|---|---|
options | array | Yes | Array of { "label": string, "value": string } |
Liquid type: string (selected value).
{
"type": "radio",
"name": "alignment",
"label": "Content alignment",
"options": [
{ "label": "Left", "value": "left" },
{ "label": "Centre", "value": "centre" },
{ "label": "Right", "value": "right" }
],
"defaultValue": "left"
}select
Dropdown selection.
| Property | Type | Required | Description |
|---|---|---|---|
options | array | Yes | Array of { "label": string, "value": string } |
Liquid type: string (selected value), or array of strings when hasMany is true.
{
"type": "select",
"name": "theme_variant",
"label": "Theme variant",
"options": [
{ "label": "Light", "value": "light" },
{ "label": "Dark", "value": "dark" },
{ "label": "Transparent", "value": "transparent" }
],
"defaultValue": "light"
}code
Code editor input. Liquid type: string.
{ "type": "code", "name": "custom_css", "label": "Custom CSS" }json
JSON editor input. Liquid type: parsed object or array.
{ "type": "json", "name": "configuration", "label": "Widget configuration" }richText
Rich text editor. Also accepted as richtext (normalised).
Liquid type: Two properties:
block.[name]— boolean,trueif content exists.block.[name]_html— string, the rendered HTML.
{ "type": "richText", "name": "content", "label": "Content" }{% if block.content %}
<div class="rich-text">{{ block.content_html }}</div>
{% endif %}hidden
Hidden field — not displayed in the admin. Useful for internal metadata. Liquid type: string.
{ "type": "hidden", "name": "block_version", "label": "Block version", "defaultValue": "2" }relationship
Reference to one or more documents from a collection.
| Property | Type | Required | Description |
|---|---|---|---|
relationTo | string | Yes | The collection slug (e.g. events, venues, pages) |
Liquid type: object (single relationship) or array of objects (multi-value). Each object contains the flattened document data plus a __collection hint.
{
"type": "relationship",
"name": "featured_venue",
"label": "Featured venue",
"relationTo": "venues"
}{% if block.featured_venue %}
<a href="/venues/{{ block.featured_venue.slug }}">{{ block.featured_venue.title }}</a>
{% endif %}upload
Media file upload (images, documents, audio, video).
Liquid type: object with media properties (url, src, alt, width, height, filename, mimeType).
{ "type": "upload", "name": "background_image", "label": "Background image" }{% if block.background_image %}
<img
src="{{ block.background_image | image_url: width: 1200 }}"
alt="{{ block.background_image.alt }}"
width="{{ block.background_image.width }}"
height="{{ block.background_image.height }}"
>
{% endif %}array
Repeatable group of fields. Creates an array of objects, each containing the nested fields.
| Property | Type | Required | Description |
|---|---|---|---|
fields | array | Yes | Array of field definitions (same format as settings) |
Liquid type: array of objects.
{
"type": "array",
"name": "testimonials",
"label": "Testimonials",
"fields": [
{ "type": "text", "name": "quote", "label": "Quote", "required": true },
{ "type": "text", "name": "author", "label": "Author name" },
{ "type": "text", "name": "role", "label": "Author role" }
]
}{% for testimonial in block.testimonials %}
<blockquote>
<p>{{ testimonial.quote }}</p>
<footer>{{ testimonial.author }}, {{ testimonial.role }}</footer>
</blockquote>
{% endfor %}group
Single nested group of fields. Creates one object containing the nested fields.
| Property | Type | Required | Description |
|---|---|---|---|
fields | array | Yes | Array of field definitions (same format as settings) |
Liquid type: object.
{
"type": "group",
"name": "cta_button",
"label": "Call to action button",
"fields": [
{ "type": "text", "name": "label", "label": "Button text", "defaultValue": "Learn more" },
{ "type": "url", "name": "url", "label": "Button link" },
{ "type": "checkbox", "name": "new_tab", "label": "Open in new tab", "defaultValue": false }
]
}{% if block.cta_button.url != blank %}
<a
href="{{ block.cta_button.url }}"
class="button"
{% if block.cta_button.new_tab %}target="_blank" rel="noopener"{% endif %}
>
{{ block.cta_button.label }}
</a>
{% endif %}Nesting
array and group support nested fields arrays. They can also nest within each other.
Maximum nesting depth: 6 layers. The validator warns when nesting exceeds 4 layers. Keep nesting shallow for editor usability.
Two-level example:
{
"type": "array",
"name": "sections",
"label": "Content sections",
"fields": [
{ "type": "text", "name": "title", "label": "Section title" },
{
"type": "group",
"name": "style",
"label": "Section style",
"fields": [
{ "type": "color", "name": "background", "label": "Background colour" },
{ "type": "select", "name": "width", "label": "Width", "options": [
{ "label": "Narrow", "value": "narrow" },
{ "label": "Wide", "value": "wide" }
]}
]
}
]
}Validation rules
| Rule | Level | Description |
|---|---|---|
Missing name | error | Block schema must include name. |
Missing settings | error | Block schema must include a settings array. |
| Invalid JSON | error | The {% schema %} content must be valid JSON. |
| Unknown field type | warning | Field type must be one of the allowed types. |
Missing singular | warning | Defaults to name if absent. |
Missing plural | warning | Defaults to name if absent. |
Missing label | warning | Defaults to name if absent. |
Missing field type | warning | Defaults to text if absent. |
| Nesting depth > 4 | warning | Consider simplifying. |
Duplicate block name | warning | Block names must be unique across the theme. |
Type normalisation
The validator normalises common case variations:
| Input | Normalised |
|---|---|
richtext | richText |
textarea | textArea |
datetime | dateTime |
Index
Text inputs: text, textArea, email, url, code
Numeric and date: number, date, dateTime
Boolean: checkbox, switch
Selection: radio, select
Rich content: richText, json, color
Relationships and media: relationship, upload
Container types: array, group
Utility: hidden
Related
- Blocks — using schemas in block files.
- Rendering blocks — the
stageblockstag. - Templates — template settings use the same field types.
- Template context — data flattening behaviour.