Shopify sections power nearly every modern theme. They let merchants drag, drop, and reorder content without touching code. For developers, they offer a structured way to ship reusable, configurable blocks that marketing teams can control on their own.

In this guide, you will learn how to build a custom Shopify section from scratch using Liquid and JSON schema. We will cover the file structure, the schema format, blocks, settings, and a complete working example. By the end, you will have a section you can drop into any Online Store 2.0 theme.

## What Is a Shopify Section?

A section is a modular template file stored in the `sections` folder of your theme. Each section mixes two things:

– Liquid markup that renders the HTML.
– A JSON schema block that defines the settings merchants edit in the theme editor.

Online Store 2.0 made sections even more powerful. You can now add sections to any page template through JSON templates, not just the homepage. That shift turned Shopify custom sections into the primary building block of theme development.

If you are new to Liquid itself, start with our [Shopify Liquid tutorial] before diving into schema work. It covers the syntax basics you will use throughout this article.

## Why Build Custom Sections Instead of Hardcoding

Hardcoding content locks merchants out. Every copy change becomes a developer ticket. Custom sections flip that model.

Here is how the two approaches compare:

| Factor | Hardcoded HTML | Custom Section |
|:——-|:—————|:—————|
| Merchant editing | Needs a developer | Self-service in editor |
| Reusability | Copy and paste | Add anywhere instantly |
| Maintenance cost | High over time | Low, centralized logic |
| Flexibility | Fixed layout | Configurable settings |
| Error risk | Easy to break theme | Isolated and safe |

The payoff is clear. When you build Shopify sections correctly, you reduce support load and give your clients real control over their store.

## Anatomy of a Section File

Every section file has a consistent structure. Understanding each part makes the rest of this guide easy to follow.

A section contains three zones:

1. Liquid markup at the top.
2. CSS, either inline or linked.
3. A `{% schema %}` block at the bottom with JSON configuration.

Only one `{% schema %}` tag is allowed per file. Shopify parses it to generate the editor controls.

Here is the skeleton of a section file:

“`liquid
{% comment %} Liquid markup goes here {% endcomment %}

{{ section.settings.heading }}

{% schema %}
{
“name”: “Custom Section”,
“settings”: [] }
{% endschema %}
“`

The `name` field shows up in the theme editor sidebar. The `settings` array holds every control the merchant can adjust.

## Understanding the JSON Schema

The JSON schema is the heart of a Shopify section. It defines settings, blocks, presets, and limits. Shopify reads this object to build the editor interface.

The top-level schema keys you will use most often are:

| Key | Purpose |
|:—-|:——–|
| `name` | Label shown in the editor |
| `settings` | Section-wide input controls |
| `blocks` | Repeatable nested content items |
| `max_blocks` | Caps the number of blocks |
| `presets` | Default configuration for new sections |
| `class` | CSS class added to the section wrapper |
| `tag` | HTML tag used to wrap the section |

Getting the schema right matters for Shopify JSON schema sections. A malformed schema breaks the editor, so always validate your JSON.

## Setting Types You Can Use

Shopify offers a wide range of input types. Each maps to a UI control in the editor. Picking the right type keeps the merchant experience clean.

Common input setting types include:

| Type | Use Case |
|:—–|:———|
| `text` | Single-line copy |
| `textarea` | Longer paragraphs |
| `richtext` | Formatted text with links |
| `image_picker` | Upload or select an image |
| `url` | Internal or external links |
| `color` | Color swatch picker |
| `range` | Numeric slider |
| `select` | Dropdown choices |
| `checkbox` | Boolean toggle |
| `product` | Product reference |
| `collection` | Collection reference |

There are also sidebar-only types like `header` and `paragraph`. These add structure and help text but do not store values.

## Building a Real Section Step by Step

Let us build a practical section: a feature highlight banner with a heading, subtext, button, and repeatable feature blocks. This example covers settings and blocks together.

### Step 1: Create the Section File

Inside your theme, create a new file at `sections/feature-banner.liquid`. Shopify picks up the filename as the section type.

### Step 2: Add the Liquid Markup

Start with markup that reads from `section.settings` and loops over blocks.

“`liquid

{{ section.settings.heading }}

{{ section.settings.subtext }}

{% if section.settings.button_label != blank %}

{{ section.settings.button_label }}

{% endif %}

{% for block in section.blocks %}

{% if block.settings.icon != blank %}
{{ block.settings.title }}
{% endif %}

{{ block.settings.title }}

{{ block.settings.description }}

{% endfor %}

“`

Notice the `{{ block.shopify_attributes }}` output. This is required for live editor features like click-to-select and drag-to-reorder.

### Step 3: Define the Schema

Now add the schema block. This defines the section settings and the repeatable blocks.

“`json
{% schema %}
{
“name”: “Feature Banner”,
“tag”: “section”,
“class”: “feature-banner-wrapper”,
“settings”: [
{
“type”: “text”,
“id”: “heading”,
“label”: “Heading”,
“default”: “Why Choose Us”
},
{
“type”: “richtext”,
“id”: “subtext”,
“label”: “Subtext”
},
{
“type”: “color”,
“id”: “bg_color”,
“label”: “Background color”,
“default”: “#f5f5f5”
},
{
“type”: “text”,
“id”: “button_label”,
“label”: “Button label”
},
{
“type”: “url”,
“id”: “button_url”,
“label”: “Button link”
}
],
“blocks”: [
{
“type”: “feature”,
“name”: “Feature”,
“settings”: [
{
“type”: “image_picker”,
“id”: “icon”,
“label”: “Icon”
},
{
“type”: “text”,
“id”: “title”,
“label”: “Feature title”,
“default”: “Feature”
},
{
“type”: “textarea”,
“id”: “description”,
“label”: “Feature description”
}
] }
],
“max_blocks”: 6,
“presets”: [
{
“name”: “Feature Banner”,
“blocks”: [
{ “type”: “feature” },
{ “type”: “feature” },
{ “type”: “feature” }
] }
] }
{% endschema %}
“`

The `presets` array is important. It tells Shopify how to populate the section when a merchant adds it fresh. Without presets, the section will not appear in the “Add section” menu.

### Step 4: Preview and Test

Save the file, open the theme editor, and add your new section. You should see the heading field, color picker, and feature blocks ready to edit.

Before shipping, run your changes through a safe workflow. Our guide on [Shopify theme testing and version control with Git] walks through branching and preview themes so you never overwrite live code.

## Working With Blocks in Depth

Blocks are repeatable sub-components inside a section. They unlock flexible layouts where merchants add as many items as they need.

Each block has its own `type`, `name`, and `settings`. You loop over `section.blocks` in Liquid and read each block’s settings independently.

A few rules to remember:

– The `type` value must be unique within the blocks array.
– Use `max_blocks` to prevent layout breakage.
– Always render `{{ block.shopify_attributes }}` on the block wrapper.
– A section can define multiple block types for mixed content.

Multiple block types let you mix, say, a text block and an image block in the same section. The merchant then chooses which to add.

## Connecting Sections to Dynamic Data

Static settings are useful, but dynamic data is where sections shine. You can pull products, collections, and metafields directly into your section.

For product-driven sections, use the `product` setting type and access fields through the product object. For deeper structured content, Shopify metafields are the right tool. Our [Shopify metafields guide] explains how to model and surface custom data inside your Liquid templates.

Here is how to read a product metafield inside a section:

“`liquid
{% assign product = section.settings.featured_product %}

{{ product.title }}

{{ product.metafields.custom.highlight.value }}

“`

This pattern keeps content structured and reusable across your store. It also pairs well with solid [Shopify data mapping strategies] when you sync external content into metafields.

## Performance Considerations

Sections can slow a theme if you are careless. Heavy loops, large images, and inline scripts add up fast.

Keep these performance habits in mind:

– Lazy-load images with `loading=”lazy”`.
– Use `image_url` filters with explicit widths.
– Avoid rendering hidden blocks unnecessarily.
– Scope CSS to the section class to prevent bleed.

For a deeper look at tuning your templates, read our breakdown of [Shopify Liquid optimization]. It covers render-blocking patterns and cleaner loops that directly affect section speed.

## Section Settings vs Theme Settings

Developers often confuse section settings with global theme settings. They serve different scopes.

| Aspect | Section Settings | Theme Settings |
|:——-|:—————–|:—————|
| Scope | One section instance | Entire theme |
| File location | Section file schema | `config/settings_schema.json` |
| Access in Liquid | `section.settings.x` | `settings.x` |
| Use case | Local content control | Brand-wide defaults |

Use section settings for content that changes per placement. Use theme settings for colors, fonts, and store-wide defaults.

## Organizing Sections at Scale

On large builds, section sprawl becomes a real problem. A disciplined structure saves you later.

Adopt these conventions early:

– Name files by function, like `hero-banner` or `product-grid`.
– Group shared logic into snippets you render inside sections.
– Document each section’s settings in a shared README.
– Keep schema defaults sensible so new sections look good instantly.

If your store integrates with external systems, your front end often reflects synced data. Teams building those pipelines lean on patterns from our [Shopify ETL pipeline] and [Shopify CRM synchronization] guides to keep that data accurate before it ever reaches a section.

## When Sections Are Not Enough

Liquid sections cover most storefront needs. But some experiences demand more.

For checkout customization, sections do not apply. You need [Shopify checkout UI extensions] instead, which run in a separate sandboxed environment.

For highly interactive, app-like storefronts, a headless approach may serve you better. Our comparison of [Shopify Hydrogen vs Liquid] helps you decide when to leave the Liquid world entirely.

And if you need custom backend logic tied to your sections, consider [building a Shopify app] to power the data behind them. Apps let you process events through [Shopify webhooks] and keep your storefront in sync with real-time changes.

For enterprise stores where section content depends on live inventory, reliable backend plumbing matters. Teams often combine section work with [reliable Shopify webhook consumers] and a [high-performance Shopify API client] to feed accurate data into the storefront.

## Common Mistakes to Avoid

New developers hit the same snags repeatedly. Watch for these.

– Forgetting `presets`, so the section never appears in the menu.
– Reusing an `id` across settings, which causes data collisions.
– Skipping `{{ block.shopify_attributes }}`, breaking editor interaction.
– Writing invalid JSON, which breaks the whole schema.
– Hardcoding values that should be settings.

A quick JSON lint before every commit prevents most of these. Pairing that with disciplined [Shopify theme version control] means a broken schema never reaches production.

## Final Thoughts

Custom sections are the backbone of flexible Shopify themes. They combine Liquid rendering with a JSON schema that hands real control to merchants. Master this pattern and your theme work becomes faster, cleaner, and far easier to maintain.

Start small with a single configurable section. Add blocks, connect dynamic data, and layer in metafields as your confidence grows. With solid Shopify theme sections development skills, you can ship store experiences that scale with any business.

If you want expert help architecting themes or the data systems behind them, our team builds production-grade Shopify solutions that hold up under real traffic.

## FAQs

### What is a Shopify section?

A Shopify section is a reusable theme file that combines Liquid markup with a JSON schema. The schema defines editable settings so merchants can configure content directly in the theme editor.

### Why does my custom section not show in the editor?

The most common cause is a missing `presets` array in your schema. Without at least one preset, Shopify will not list the section in the “Add section” menu.

### Can a section have multiple block types?

Yes. You can define several block types in the `blocks` array, each with its own settings. Merchants then choose which block type to add when building the layout.

### What is the difference between settings and blocks?

Settings are fixed, section-wide controls. Blocks are repeatable sub-items that merchants can add, remove, and reorder within the same section.

### How many blocks can a section have?

By default, a section supports up to 50 blocks. You can lower this limit using the `max_blocks` key to protect your layout from breaking.

### Do I need to know JavaScript to build sections?

No. Basic sections only require Liquid and JSON. JavaScript is optional and only needed for interactive features like sliders or tabs.

Your Trusted Shopify Partner.

Get in touch with our expert Shopify consultants today and let’s discuss your ideas and business requirements.