Shopify Section Schema: Tag, Settings, Blocks & Input Types (2026 Reference)

Section schema is the invisible foundation of every Shopify merchant's customizer experience. Get it right, and merchants build beautiful pages confidently. Get it wrong, and you end up with confused merchants, support requests, and sections that no one uses correctly.
This guide covers Shopify section schema from foundational principles through every input type, block architecture patterns, metafield connections, and the settings_schema.json global theme settings system. Whether you're building your first custom section or reviewing an existing theme's schema for quality, this is the reference you need.
Table of Contents
- What Is Shopify Section Schema?
- Section Schema vs. Block Schema: The Core Distinction
- Every Shopify Schema Input Type Explained
- Block Schema Architecture
- Metafield Connections in Section Schema
- settings_schema.json — Global Theme Settings
- Schema Design Best Practices
- Common Schema Mistakes to Avoid
- Frequently Asked Questions
What Is Shopify Section Schema?
Every Shopify section file (.liquid) contains a {% schema %} tag at the bottom. This is a JSON block that defines everything the Shopify theme customizer needs to know about the section: its name, what settings a merchant can configure, what block types are available within it, and validation rules like maximum block counts.
Here's a minimal section schema:
{% schema %}
{
"name": "Featured Products",
"settings": [
{
"type": "text",
"id": "heading",
"label": "Section heading",
"default": "Featured Products"
},
{
"type": "range",
"id": "columns",
"label": "Products per row",
"min": 2,
"max": 4,
"step": 1,
"default": 3
}
],
"presets": [
{
"name": "Featured Products"
}
]
}
{% endschema %}
The presets array is what makes the section available in the "Add section" menu in the theme customizer. Without a preset, the section exists but merchants can't add it — only template editors can reference it in JSON templates.
Section Schema vs. Block Schema: The Core Distinction
Before diving into input types, the most important design decision in any section schema is: what belongs in section settings vs. what belongs in block settings?
Section settings are configured once per section instance and apply uniformly across the entire section. If a merchant can only set one value for the entire section — not a different value for each content item — it goes in section settings.
Examples of section settings:
- Section heading
- Number of columns
- Background color
- Padding and spacing controls
- Whether to show or hide a sub-element (like a "View all" button)
Block settings are configured individually for each block instance within the section. Every block of the same type has its own values for every block setting, independently of every other block.
Examples of block settings:
- Each testimonial's author name and quote text
- Each feature's icon, title, and description
- Each FAQ's question and answer
- Each logo's image and company name
The rule: if the content varies per item, it's a block setting. If it controls the whole section, it's a section setting.
Every Shopify Schema Input Type Explained
Shopify's section schema supports 20+ input types. Using the right type for each setting is critical — not just technically, but for merchant UX. Here's every input type with when to use each:
Text Inputs
text — Single-line text input. Use for short strings: headings, labels, button text. Do not use for multi-paragraph content.
{
"type": "text",
"id": "cta_label",
"label": "Button label",
"default": "Shop now"
}
textarea — Multi-line text input without formatting. Use for short descriptions where rich text formatting isn't needed but the content may span multiple sentences.
richtext — Rich text editor with bold, italic, links, and lists. Use this for any merchant-facing content that may need formatting. Do not use textarea when a merchant might reasonably want to bold a word or add a link.
html — Raw HTML input. Renders as unescaped HTML in the template. Use sparingly and only for advanced users. Most merchant-facing text content should use richtext, not html.
inline_richtext — Rich text without block-level elements (no paragraphs, no lists). Use for text in inline contexts — a product badge label where you want bold/italic but not line breaks.
Media Inputs
image_picker — Image upload with Shopify's native image uploader. Always use this for images, not url or text. The image_picker returns a Shopify image object that supports responsive sizing via image_url.
{
"type": "image_picker",
"id": "hero_image",
"label": "Hero image"
}
Access in Liquid: {{ section.settings.hero_image | image_url: width: 1200 }}
video — Native Shopify video object picker (from Shopify Files). Use for Shopify-hosted videos.
video_url — YouTube or Vimeo URL input. Use when merchants paste external video URLs rather than uploading files. Validates that the URL is from an accepted video host.
{
"type": "video_url",
"id": "promo_video",
"label": "Promo video URL",
"accept": ["youtube", "vimeo"]
}
Color & Typography
color — Native color picker. Returns a hex value. Use for any configurable color in the section.
color_scheme — Color scheme selector tied to the theme's predefined color schemes (configured in settings_schema.json). Preferred over individual color settings when your sections should respect theme color schemes rather than arbitrary colors. Changing a theme color scheme then updates all sections using that scheme automatically.
color_background — Specifically for background color use cases. Supports gradient inputs in addition to solid colors.
font_picker — Google Font family picker. Returns a font object. Use when sections should offer configurable typography. Note: the font object must be loaded via font_url in the CSS before use.
Numeric Inputs
range — Numeric slider with min, max, and step. Perfect for spacing controls, column counts, font size scales, and any numeric value that has a clear range. Always preferred over text for numeric values that have meaningful min/max constraints.
{
"type": "range",
"id": "padding_top",
"label": "Top padding",
"min": 0,
"max": 100,
"step": 4,
"unit": "px",
"default": 40
}
number — Free-form numeric input without a range constraint. Use when the valid range is unbounded or very large.
Selection Inputs
select — Dropdown with predefined options. Use whenever there are a fixed set of valid choices. Never use text for settings that have a limited set of valid values.
{
"type": "select",
"id": "layout",
"label": "Section layout",
"options": [
{ "value": "grid", "label": "Grid" },
{ "value": "carousel", "label": "Carousel" },
{ "value": "list", "label": "List" }
],
"default": "grid"
}
radio — Radio button group. Functionally identical to select but displayed as inline radio buttons rather than a dropdown. Use for options where seeing all choices simultaneously improves the decision (2–4 options) and the labels are short.
checkbox — Boolean toggle. Use for on/off options: "Show section heading", "Enable autoplay", "Show border". The most useful input type for merchant UX — clear, unambiguous, and fast to configure.
Reference Inputs
These allow merchants to select Shopify objects directly:
product — Product picker. Returns a product object.
collection — Collection picker.
article — Blog article picker.
page — Page picker.
blog — Blog picker.
product_list — Multi-product picker. Allows selecting multiple products (up to 12 by default).
collection_list — Multi-collection picker.
metaobject — Metaobject reference picker. Allows merchants to select a specific metaobject entry. Use when sections display structured content that is managed as metaobjects (team members, case studies, specifications).
Other Inputs
url — URL input. Validates that the value is a valid URL (internal Shopify paths or external URLs). Use for links, not for images or media.
link_list — Navigation menu picker. Returns a Shopify linklists object. Use for sections that render navigation menus (footer columns, mega-menu panels).
liquid — Raw Liquid code input for advanced users. Renders as executed Liquid in the template. Use extremely sparingly — only in themes where developers are the intended editors.
Structural Elements
These aren't input types — they're layout helpers for the settings panel:
header — Adds a text header to group settings visually in the customizer.
paragraph — Adds descriptive text to explain a group of settings.
{
"type": "header",
"content": "Layout settings"
},
{
"type": "paragraph",
"content": "Control the spacing and column count for this section."
}
Use header to logically group related settings. A section with 8+ settings should have at least 2–3 headers organizing them into clear groups.
Block Schema Architecture
Blocks are defined within the "blocks" array of the section schema. Each block type definition has:
"type"— A unique identifier for this block type (string, no spaces)"name"— The display name shown in the customizer"limit"— Optional maximum number of this block type per section instance"settings"— Array of input settings for this block type (same input types as section settings)
{
"name": "Testimonials",
"blocks": [
{
"type": "testimonial",
"name": "Testimonial",
"settings": [
{
"type": "richtext",
"id": "quote",
"label": "Quote"
},
{
"type": "text",
"id": "author",
"label": "Author name"
},
{
"type": "text",
"id": "author_role",
"label": "Author role",
"default": "Customer"
},
{
"type": "image_picker",
"id": "author_photo",
"label": "Author photo"
},
{
"type": "range",
"id": "rating",
"label": "Star rating",
"min": 1,
"max": 5,
"step": 1,
"default": 5
}
]
}
],
"max_blocks": 10
}
Blocks are accessed in Liquid via the section.blocks array:
{% for block in section.blocks %}
{% if block.type == 'testimonial' %}
<blockquote {{ block.shopify_attributes }}>
{{ block.settings.quote }}
<cite>{{ block.settings.author }}, {{ block.settings.author_role }}</cite>
</blockquote>
{% endif %}
{% endfor %}
The {{ block.shopify_attributes }} Liquid tag is required on the block's root element to enable the customizer's click-to-select functionality. Always include it.
Multiple Block Types in One Section
A section can contain multiple block types. The @app reserved block type allows apps to inject their own blocks into the section via theme app extensions:
"blocks": [
{ "type": "@app" },
{
"type": "feature",
"name": "Feature",
"settings": [...]
},
{
"type": "testimonial",
"name": "Testimonial",
"settings": [...]
}
]
Including { "type": "@app" } is essential for sections that should support app blocks from third-party Shopify apps.
Metafield Connections in Section Schema
Shopify 2.0 supports metafield connections in section settings — allowing a section setting to pull its default value from a product, collection, or other resource's metafield, rather than requiring the merchant to manually enter the content.
A metafield-connected setting uses the "info" property and references a specific metafield namespace and key:
{
"type": "text",
"id": "product_subtitle",
"label": "Product subtitle",
"info": "Leave blank to use the product metafield value automatically."
}
For direct metafield display without a section setting override, access the metafield directly in Liquid:
{% assign subtitle = product.metafields.custom.subtitle %}
{% if subtitle != blank %}
<p class="product-subtitle">{{ subtitle }}</p>
{% elsif section.settings.product_subtitle != blank %}
<p class="product-subtitle">{{ section.settings.product_subtitle }}</p>
{% endif %}
This pattern — metafield as the default, section setting as the override — gives merchants the flexibility to customize individual instances while benefiting from automatic metafield data for most use cases.
settings_schema.json — Global Theme Settings
The settings_schema.json file in your theme's config directory defines the global settings available across the entire theme — colors, typography, spacing, and behavior toggles that apply site-wide.
It follows a similar structure to section schema, but settings are organized into named sections (displayed as tabs or groups in the theme editor):
[
{
"name": "Colors",
"settings": [
{
"type": "color_scheme_group",
"id": "color_schemes",
"label": "Color schemes",
"definition": [
{
"type": "color",
"id": "background",
"label": "Background",
"default": "#ffffff"
},
{
"type": "color",
"id": "text",
"label": "Text",
"default": "#121212"
},
{
"type": "color",
"id": "primary",
"label": "Primary accent",
"default": "#1B4FD8"
}
],
"role": {
"background": "background",
"text": "text"
}
}
]
},
{
"name": "Typography",
"settings": [
{
"type": "font_picker",
"id": "heading_font",
"label": "Heading font",
"default": "helvetica_n4"
},
{
"type": "font_picker",
"id": "body_font",
"label": "Body font",
"default": "helvetica_n4"
}
]
}
]
Global settings are accessed in Liquid via settings.setting_id (not section.settings). For example: {{ settings.heading_font | font_face }}.
Schema Design Best Practices
After designing 500+ section schemas, these are the patterns that consistently produce schemas merchants find intuitive:
1. Order settings to match the visual top-to-bottom reading order of the section. If the section has a badge, then a heading, then a description, then a CTA button, the settings should appear in that exact order. Merchants mentally map settings to what they see in the preview — when settings don't match the visual order, they get confused.
2. Use header elements to group related settings. Any section with more than 6 settings needs grouping. Common groups: Content, Layout, Colors, Style. Don't put all settings in one undivided list.
3. Always set default values for every setting. Sections should look reasonable before a merchant configures anything. A section that looks broken until every field is filled creates a bad first impression during onboarding.
4. Use info text to explain non-obvious settings. The info property adds a small help text below the setting. Use it when the setting's purpose isn't completely obvious from the label alone.
5. Prefer select over text for any setting with a fixed set of valid values. Free-text input for settings like "layout: grid or list" is a UX failure — merchants can mistype, and there's no fallback for invalid values.
6. Use checkbox for boolean features. "Show heading", "Enable autoplay", "Display border" are all checkboxes, not text fields asking for "yes" or "no".
7. Define max_blocks for block-heavy sections. An unlimited testimonials section that a merchant fills with 50 testimonials will break layouts and performance. Set max_blocks to a number that makes design sense for the section (typically 3–12).
Common Schema Mistakes to Avoid
Using text for everything. The most common schema quality problem. When every setting is a text input, merchants are responsible for remembering what format each field expects. Use the specific input type for each content type.
Schema settings out of visual order. If the first setting in the panel is the CTA button label and the last is the heading, merchants have to hunt for each setting. Always match visual order.
Missing presets. A section without a presets entry can't be added by merchants — it can only be placed in JSON templates by developers. If merchants should be able to add the section, add a preset.
No defaults on any settings. A section with all empty defaults looks broken until manually configured. Always set sensible defaults so the section renders something meaningful immediately.
Blocks without {{ block.shopify_attributes }} — The customizer won't highlight blocks on click, breaking the editing experience.
Using html input type for merchant-facing content. Raw HTML inputs should only be used in developer-oriented admin themes, not in sections merchants will edit. Use richtext for formatted text.
Frequently Asked Questions
What is the maximum number of settings in a Shopify section schema?
Shopify doesn't publish a hard limit on the number of settings per section, but sections with more than 20 settings become difficult to manage in the customizer. If you find yourself needing more than 15–20 settings, consider splitting the section into multiple sections or using block types to handle repeatable content elements.
Can blocks have their own blocks in Shopify schema?
No — Shopify section schema supports only one level of block nesting. Sections contain blocks, but blocks cannot contain their own sub-blocks. If you need nested repeatable content, consider using a separate section that references a metaobject, or restructuring the content model.
How do I make a setting visible only when another setting has a specific value?
Shopify section schema doesn't support conditional setting visibility natively. If a setting only makes sense when a checkbox is enabled (e.g., "Animation speed" should only show when "Enable animation" is checked), the usual approach is to group these settings together with a header and use info text explaining that the setting only applies when the related toggle is on.
Can I reference theme settings inside a section schema?
No — section schema is self-contained. You can access global settings values within your section's Liquid template, but you can't reference global settings from within the schema JSON itself. This is why it's important to use the color_scheme input type in sections rather than color — schemes inherit from global settings while standalone color settings are independent.
How do I add a section to a specific page template?
Sections are added to page templates via the JSON template file (e.g., templates/product.json). Each JSON template contains a "sections" object listing the sections in the template. When you add a section to a JSON template, it appears at that position on that template type for every store that uses it, unless overridden per-page in the customizer.
Need Custom Section Schema Development?
If you're building custom sections for a Shopify store and want them built with correctly designed schema from the start, our Shopify custom sections development service includes professional schema design as part of every section build.
We also offer standalone Shopify section schema development for teams that need schema architecture work on existing sections — auditing, improving, and refactoring schema to best-practice patterns.
Building a new Shopify store or migrating an existing one? Our custom Shopify development service and Shopify migration service include full schema architecture for every custom section we build.
For the most technically demanding stores, see our dynamic sections service for metafield-connected, personalized section architecture.
Alex Sterling
Senior Shopify Developer
Expert in web development, digital marketing, and helping businesses grow their online presence.