Shopify Section Schema Explained
Demystify Shopify's JSON schema syntax. Learn how to connect your Liquid HTML to the Theme Editor settings seamlessly.
Share with Shopify developers — useful guides spread faster in theme dev communities.
What schema controls
The {% schema %} JSON block at the bottom of a section file defines the theme editor sidebar: setting types, block types, presets, and limits. Without valid schema, merchants cannot edit your section without a code deploy. A practical implementation usually needs three pieces: name, settings or blocks, and at least one preset.
Valid JSON structure
Schema must parse as strict JSON—no trailing commas, no comments. One invalid character prevents the entire section from registering in the editor.
{% schema %}
{
"name": "Custom Banner",
"tag": "section",
"class": "banner-section",
"settings": [
{
"type": "text",
"id": "heading",
"label": "Heading",
"default": "Welcome"
},
{
"type": "image_picker",
"id": "image",
"label": "Background image"
}
],
"presets": [{ "name": "Custom Banner" }]
}
{% endschema %}
Mapping ids to Liquid
Each setting id becomes section.settings.id. Typos fail silently—empty output with no error message.
<div class="banner">
<h2>{{ section.settings.heading | escape }}</h2>
{% if section.settings.image != blank %}
{{ section.settings.image | image_url: width: 1600 | image_tag: loading: 'lazy' }}
{% endif %}
</div>
Blocks, presets, and limits
blocks define repeatable row types (FAQ items, slides). presets make the section appear in Add section on JSON templates. Use max_blocks on sliders and logo strips—unlimited image blocks slow the editor and storefront.
"blocks": [
{
"type": "slide",
"name": "Slide",
"settings": [
{ "type": "image_picker", "id": "image", "label": "Image" }
]
}
],
"max_blocks": 6
Setting types that map cleanly
text+| escapefor short labelsrichtextinside a.rtewrapper for formatted copyurlfor links—not a text field labeled "URL"checkboxfor show/hide togglesselectfor layout variants
Common schema mistakes
- Missing
presets— section invisible in Add section - Duplicate setting ids across blocks — unpredictable overwrites
textused whereurlbelongs — broken links in production
Takeaway
Schema is the contract between Liquid and the merchant sidebar. For flat vs repeatable rows, read Flat vs Block Sections. Generate first-pass JSON from markup via the converter workspace or Schema Generator.
Schema mistakes that break the theme editor
Trailing commas in JSON prevent the entire section from registering—merchants see nothing in Add section. Duplicate setting ids across blocks cause unpredictable overwrites. Using text for a URL field lets merchants paste https:// into a setting labeled "Button label." We fix these on every code review before merge.
Merchant-first schema decisions
Labels matter more than ids. "Main headline" beats "Heading 1." Group long lists with header settings: Content, Layout, Colors. Seed defaults from approved copy so empty sections do not look broken in client demos. Patterns from merchant-friendly schema apply here.
Block schema in production
"blocks": [
{
"type": "feature",
"name": "Feature card",
"settings": [
{ "type": "text", "id": "title", "label": "Title", "default": "Free shipping" },
{ "type": "richtext", "id": "body", "label": "Description" }
]
}
],
"max_blocks": 8
Set max_blocks on logo strips and sliders—unlimited rows with full-width images slow the editor and storefront.
Validation checklist
- JSON parses in an external linter
- Every preset references valid block types
- image_picker fields paired with blank guards in Liquid
- url settings used for links, not text settings
Troubleshooting
Section missing from Add section: add a non-empty presets array.
Setting changes do not appear: wrong id in Liquid or stale template JSON.
Blocks not selectable in editor: missing {{ block.shopify_attributes }} on the wrapper element.
Topic cluster
Schema
Section schema, settings, blocks, and theme editor integration.
Convert HTML to Shopify Liquid
Paste HTML & generate Liquid with schema, blocks, and scoped CSS. No signup required.
Share
Share this guide
Found this guide useful? Share it with other Shopify developers on LinkedIn, X, or Reddit.