Docs/Storefront/Building Custom Sections

Building Custom Sections

Create a new section type — write the markup, declare settings, and have it appear in the visual editor.

If a section type you need doesn't exist in your theme, you can build one. A custom section is a single Liquid file in sections/ with two parts: the markup at the top, and a {% schema %} block at the bottom that tells the visual editor what settings to expose.

The shape of a section file

A minimal section looks like this:

<section class="my-section">
  <h2>{{ section.settings.heading }}</h2>
  <p>{{ section.settings.body }}</p>
</section>

{% schema %}
{
  "name": "My Section",
  "settings": [
    { "id": "heading", "type": "text", "label": "Heading", "default": "Hello" },
    { "id": "body",    "type": "textarea", "label": "Body" }
  ],
  "presets": [
    { "name": "Default" }
  ]
}
{% endschema %}

Save it as sections/my-section.liquid and it shows up in the visual editor's section library immediately.

Schema basics

The schema is a JSON document inside {% schema %} ... {% endschema %}. The four most important fields:

name

The label shown in the section library and section list. Keep it short — "Featured Packages", "Hero", "FAQ".

settings

An array of every editable setting the merchant should see in the inspector. Each setting has at minimum an id (the variable name to read in Liquid via section.settings.<id>), a type (text, textarea, image, color, etc.), and a label. Optionally, a default value, an info hint, or constraints like min and max on a range.

See Editing section settings for the full type vocabulary.

blocks

If your section has repeating sub-units, declare them as block types. Each block has its own type name, label, and settings array — same shape as the section's own settings.

"blocks": [
  {
    "type": "feature",
    "name": "Feature",
    "settings": [
      { "id": "icon",  "type": "image",    "label": "Icon" },
      { "id": "title", "type": "text",     "label": "Title" },
      { "id": "body",  "type": "textarea", "label": "Description" }
    ]
  }
]

You also choose how many blocks the section can hold via "max_blocks": N. See Working with blocks.

presets

Pre-configured starting points the merchant sees in the section library. The simplest preset is just a name — clicking it inserts the section with default settings. More elaborate presets pre-fill settings and even include blocks:

"presets": [
  {
    "name": "Three features",
    "settings": { "heading": "Why us" },
    "blocks": [
      { "type": "feature", "settings": { "title": "Fast" } },
      { "type": "feature", "settings": { "title": "Reliable" } },
      { "type": "feature", "settings": { "title": "Friendly" } }
    ]
  }
]

Reading settings in your markup

Inside the section's Liquid, read settings via section.settings.<id> and blocks via section.blocks:

<section class="features">
  <h2>{{ section.settings.heading }}</h2>
  <div class="feature-grid">
    {% for block in section.blocks %}
      <div class="feature">
        <img src="{{ block.settings.icon | asset_url }}" alt="">
        <h3>{{ block.settings.title }}</h3>
        <p>{{ block.settings.body }}</p>
      </div>
    {% endfor %}
  </div>
</section>

Walkthrough: a "Pricing tiers" section

  1. Right-click sections/ in the file tree and choose New file. Name it pricing-tiers.liquid.
  2. Paste in markup that loops over blocks (each block is a tier).
  3. Add a schema block declaring the tier block type with name, price, features list, and a CTA URL.
  4. Save. Open the visual editor on Home, click + Add section, and "Pricing tiers" appears in the library.
  5. Add the section. The inspector exposes all the settings you declared. Add tier blocks with the merchant's pricing data.
  6. Save and publish.

FAQ

The section saved but doesn't appear in the visual editor.

The schema is probably malformed JSON. Open the file — the editor's linter flags missing commas, unclosed braces, or unknown fields. Fix the schema and save again; the library refreshes on the next visual editor reload.

Can sections share settings?

Each section's schema is independent. If you want consistent settings across multiple sections, copy the settings block from one schema to the other. For shared markup, use snippets — see Writing Liquid.

Where do block-type definitions live if multiple sections use the same block?

You can declare blocks inline in the section's schema (most common), or define them as standalone files in the blocks/ folder and reference them by type from any section's schema. Standalone block files are useful when several sections need the same block type.

Was this page helpful?Suggest an edit →

Updated recently