QUANTM7 Docs
QuillSections

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:

FieldRequiredDescription
nameyesThe name shown in the visual editor sidebar
tagnoThe HTML tag for the section wrapper (default: section)
classnoA CSS class added to the wrapper element
settingsnoAn array of setting definitions
blocksnoAn array of block type definitions
presetsnoDefault configurations for adding the section
max_blocksnoThe maximum number of blocks allowed

Settings

Each setting is an object with at least three fields:

FieldRequiredDescription
typeyesThe kind of input (see table below)
idyesA unique key used to access the value in the template
labelyesThe label shown in the editor form
defaultnoThe starting value before the merchant changes it
infonoHelp text shown below the input
placeholdernoPlaceholder text for text inputs
groupnoAssign this setting to a named group (see Groups below)
conditionnoShow this setting only when another field matches a value (see Conditional fields)
hiddennoSet to true to keep this field in the data but hide it from the editor form

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": "Center" },
    { "value": "right", "label": "Right" }
  ],
  "default": "left"
}

Color

{ "type": "color", "id": "text_color", "label": "Text color", "default": "#000000" }
{ "type": "color_background", "id": "bg", "label": "Background" }

The color_background type supports both solid colors 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": "quill", "id": "code", "label": "Custom Quill code" }

Full example

A banner section with an image, heading, button, and color 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 color", "default": "#f5f5f5" },
    { "type": "color", "id": "text_color", "label": "Text color", "default": "#000000" }
  ],
  "presets": [{ "name": "Banner", "category": "Image" }]
}
{% endschema %}

Groups

By default, all settings appear in a flat list. For sections with many settings, you can organise them into collapsible groups.

Define a groups array at the top level of the schema, then assign each setting to a group using the group field:

{% schema %}
{
  "name": "Hero Banner",
  "groups": [
    { "id": "style", "label": "Style" },
    { "id": "advanced", "label": "Advanced", "collapsed": true }
  ],
  "settings": [
    { "type": "text", "id": "heading", "label": "Heading" },
    { "type": "text", "id": "body", "label": "Body text" },
    { "type": "select", "id": "padding", "label": "Section padding", "group": "style",
      "options": [
        { "value": "compact", "label": "Compact" },
        { "value": "default", "label": "Default" },
        { "value": "spacious", "label": "Spacious" }
      ],
      "default": "default"
    },
    { "type": "select", "id": "btn_size", "label": "Button size", "group": "advanced",
      "options": [
        { "value": "sm", "label": "Small" },
        { "value": "default", "label": "Default" },
        { "value": "lg", "label": "Large" }
      ],
      "default": "default"
    }
  ]
}
{% endschema %}

Group properties

FieldRequiredDescription
idyesA unique key that settings reference with group
labelyesThe heading shown in the editor sidebar
collapsednoSet to true to collapse the group by default (default: true)

Settings without a group field appear at the top of the panel, above any groups. Groups with no visible settings are hidden automatically.

Conditional fields

Show a setting only when another field has a specific value. This keeps the settings panel clean by hiding fields that are not relevant to the current configuration.

{% schema %}
{
  "name": "Media Section",
  "settings": [
    { "type": "select", "id": "media_type", "label": "Media type",
      "options": [
        { "value": "image", "label": "Image" },
        { "value": "video", "label": "Video" }
      ],
      "default": "image"
    },
    { "type": "image_picker", "id": "image", "label": "Image",
      "condition": { "field": "media_type", "eq": "image" }
    },
    { "type": "video_url", "id": "video", "label": "Video URL",
      "condition": { "field": "media_type", "eq": "video" }
    }
  ]
}
{% endschema %}

When the merchant picks "Image", only the image picker shows. When they pick "Video", only the video URL field shows.

Condition operators

OperatorDescription
eqShow when the field equals this value
neqShow when the field does not equal this value
{ "type": "color", "id": "overlay_color", "label": "Overlay colour",
  "condition": { "field": "show_overlay", "neq": false }
}

The field value must be the id of another setting in the same schema.

Hidden fields

Set "hidden": true on a setting to keep it in the section data without showing it in the editor form. The field still has a default value, presets can set it, and the template can read it. It just does not appear as a control.

{ "type": "select", "id": "layout", "label": "Layout", "hidden": true, "default": "centered",
  "options": [
    { "value": "centered", "label": "Centered" },
    { "value": "split", "label": "Split" }
  ]
}

This is useful when a preset controls the value. The merchant picks a style from the preset selector, which sets the hidden field internally. There is no need for a separate dropdown that does the same thing.

On this page