Section Schema
Define settings for sections using JSON schema inside the schema tag.
Every section needs a schema. The schema tells the visual editor what settings to show in the sidebar. Merchants change these settings to control the section without editing code.
How it works
Put a {% schema %} block at the bottom of your section template. Inside it, write a JSON object that lists the settings you want:
{% schema %}
{
"name": "Hero Banner",
"settings": [
{
"type": "text",
"id": "heading",
"label": "Heading",
"default": "Welcome to our store"
}
]
}
{% endschema %}The visual editor reads this JSON and builds a form. When the merchant types a new heading, you can use it in the template:
<h1>{{ section.settings.heading }}</h1>Schema structure
The top level of the schema object has these fields:
| Field | Required | Description |
|---|---|---|
name | yes | The name shown in the visual editor sidebar |
tag | no | The HTML tag for the section wrapper (default: section) |
class | no | A CSS class added to the wrapper element |
settings | no | An array of setting definitions |
blocks | no | An array of block type definitions |
presets | no | Default configurations for adding the section |
max_blocks | no | The maximum number of blocks allowed |
Settings
Each setting is an object with at least three fields:
| Field | Required | Description |
|---|---|---|
type | yes | The kind of input (see table below) |
id | yes | A unique key used to access the value in the template |
label | yes | The label shown in the editor form |
default | no | The starting value before the merchant changes it |
info | no | Help text shown below the input |
placeholder | no | Placeholder text for text inputs |
Setting types
These are all the input types you can use in a schema:
Text inputs
{ "type": "text", "id": "heading", "label": "Heading", "default": "Hello" }{ "type": "textarea", "id": "body", "label": "Body text" }{ "type": "richtext", "id": "content", "label": "Content" }The richtext type gives the merchant a formatting toolbar. The value is an HTML string.
Numbers
{ "type": "number", "id": "speed", "label": "Scroll speed", "default": 5 }{
"type": "range",
"id": "columns",
"label": "Columns",
"min": 1,
"max": 6,
"step": 1,
"default": 3
}The range type shows a slider. You must set min, max, and step.
Boolean
{ "type": "checkbox", "id": "show_price", "label": "Show price", "default": true }Selection
{
"type": "select",
"id": "layout",
"label": "Layout",
"options": [
{ "value": "grid", "label": "Grid" },
{ "value": "list", "label": "List" },
{ "value": "carousel", "label": "Carousel" }
],
"default": "grid"
}{
"type": "radio",
"id": "alignment",
"label": "Text alignment",
"options": [
{ "value": "left", "label": "Left" },
{ "value": "center", "label": "Centre" },
{ "value": "right", "label": "Right" }
],
"default": "left"
}Colour
{ "type": "color", "id": "text_color", "label": "Text colour", "default": "#000000" }{ "type": "color_background", "id": "bg", "label": "Background" }The color_background type supports both solid colours and gradients.
Media
{ "type": "image_picker", "id": "image", "label": "Image" }{ "type": "video_url", "id": "video", "label": "Video URL" }The image_picker returns an image object. Use img_url or image_tag to display it.
Resource pickers
{ "type": "collection", "id": "collection", "label": "Collection" }{ "type": "product", "id": "featured", "label": "Featured product" }{ "type": "product_list", "id": "products", "label": "Products" }{ "type": "page", "id": "page", "label": "Page" }These let the merchant pick a product, collection, or page from the admin. The value is the full object, so you can access all its properties in the template.
Other types
{ "type": "url", "id": "link", "label": "Link URL" }{ "type": "font_picker", "id": "heading_font", "label": "Heading font" }{ "type": "html", "id": "custom", "label": "Custom HTML" }{ "type": "liquid", "id": "code", "label": "Custom Quill code" }Full example
A banner section with an image, heading, button, and colour controls:
<div class="banner" style="background: {{ section.settings.bg_color }}">
{% if section.settings.image %}
{{ section.settings.image | image_tag: class: 'banner__image' }}
{% endif %}
<div class="banner__content">
<h2 style="color: {{ section.settings.text_color }}">
{{ section.settings.heading }}
</h2>
{% if section.settings.button_text != blank %}
<a href="{{ section.settings.button_link }}" class="btn">
{{ section.settings.button_text }}
</a>
{% endif %}
</div>
</div>
{% schema %}
{
"name": "Banner",
"settings": [
{ "type": "image_picker", "id": "image", "label": "Background image" },
{ "type": "text", "id": "heading", "label": "Heading", "default": "Welcome" },
{ "type": "text", "id": "button_text", "label": "Button text" },
{ "type": "url", "id": "button_link", "label": "Button link" },
{ "type": "color", "id": "bg_color", "label": "Background colour", "default": "#f5f5f5" },
{ "type": "color", "id": "text_color", "label": "Text colour", "default": "#000000" }
],
"presets": [{ "name": "Banner", "category": "Image" }]
}
{% endschema %}