How to Create a Custom Section in Shopify

Create a custom Shopify section from scratch: the section file, its schema, example HTML and CSS, and how to add it in the theme editor — kept update-safe.

6 min readUpdated

Part of our guide to Shopify Custom Sections: The Complete Guide.

This guide walks through building a Shopify custom section from an empty file to a live, editable block on your storefront. You will end up with a "Feature banner" section — a heading, a paragraph, and a button — that a merchant can configure entirely from the theme editor. It assumes an Online Store 2.0 theme (Dawn or any theme published after mid-2021).

Before you start, work on an unpublished copy of your theme. In your Shopify admin, go to Online Store → Themes, open the menu on your live theme, and choose Duplicate. Edit the duplicate so a mistake never touches live traffic, then publish when you are happy.

What you need

  • Access to your theme's code — either the browser code editor (Themes → ⋯ → Edit code) or the Shopify CLI with a local checkout of the theme.
  • An Online Store 2.0 theme, so the section can be added and reordered in the editor rather than hard-coded into a template.

Step 1 — Create the section file

Sections live in the theme's sections/ folder. Create a new file there named feature-banner.liquid. The file name (without the extension) is the section's type — it is how templates and the editor refer to it, so keep it lowercase and hyphenated.

In the code editor: open sections, click Add a new section, and name it feature-banner. Shopify creates sections/feature-banner.liquid with a starter {% schema %} you will replace in the next steps.

Step 2 — Write the markup

At the top of the file, add the HTML for the section. Read every editable value from section.settings.<id> — those ids are defined by the schema you add in Step 3. Wrapping the markup in a class scoped to the section keeps its styles from leaking into the rest of the page.

<section class="feature-banner">
  <div class="feature-banner__inner">
    <h2 class="feature-banner__heading">{{ section.settings.heading }}</h2>
    <p class="feature-banner__text">{{ section.settings.body }}</p>
    {% if section.settings.button_label != blank %}
      <a
        class="feature-banner__button"
        href="{{ section.settings.button_link }}"
      >
        {{ section.settings.button_label }}
      </a>
    {% endif %}
  </div>
</section>

Two details that matter:

  • The {% if section.settings.button_label != blank %} guard means the button only renders when a merchant actually fills it in — an empty setting never leaves a stray, linkless button on the page.
  • Everything reads from section.settings, so nothing is hard-coded. That is what makes the section configurable in the editor.

Step 3 — Add the schema

The {% schema %} block is JSON that names the section, declares its settings, and — through presets — lets it appear in the theme editor's "Add section" menu. Add this at the bottom of the file:

{% schema %}
{
  "name": "Feature banner",
  "tag": "section",
  "settings": [
    {
      "type": "text",
      "id": "heading",
      "label": "Heading",
      "default": "Free shipping over $50"
    },
    {
      "type": "richtext",
      "id": "body",
      "label": "Body text",
      "default": "<p>Delivered in 2–4 business days.</p>"
    },
    {
      "type": "text",
      "id": "button_label",
      "label": "Button label"
    },
    {
      "type": "url",
      "id": "button_link",
      "label": "Button link"
    }
  ],
  "presets": [
    { "name": "Feature banner" }
  ]
}
{% endschema %}

Key points:

  • Each id in the schema is what you read as section.settings.<id> in the markup — they must match exactly.
  • presets is what lets the section be added from the editor. Without it, the section exists but cannot be inserted onto a page.
  • The schema must be valid JSON. A trailing comma or an unquoted key will make the section fail to load, so paste it whole rather than typing it by hand.

Step 4 — Style the section

Add the CSS. The safest place is a {% stylesheet %} block inside the same section file — Shopify collects it into the theme's stylesheet, and scoping every rule to the .feature-banner class keeps it from colliding with the theme.

{% stylesheet %}
.feature-banner {
  padding: 3rem 1.5rem;
  background: #f4f4f2;
}
.feature-banner__inner {
  max-width: 60rem;
  margin: 0 auto;
  text-align: center;
}
.feature-banner__heading {
  font-size: 1.75rem;
  margin: 0 0 0.5rem;
}
.feature-banner__button {
  display: inline-block;
  margin-top: 1rem;
  padding: 0.75rem 1.5rem;
  border-radius: 0.375rem;
  background: #008060;
  color: #fff;
  text-decoration: none;
}
{% endstylesheet %}

If you would rather keep the CSS separate, or need it to react to the theme's own color scheme, see How to add custom CSS to a section for the trade-offs between a {% stylesheet %} block, an assets/ file, and the theme editor's built-in color settings.

Step 5 — Add it in the theme editor

Save the file, then open the theme editor: Online Store → Themes → Customize. On any template, click Add section, find Feature banner in the list (it appears because of the presets entry), and add it. Fill in the heading, body, and button, drag it to where you want it, and Save.

That is the full loop: a merchant can now configure this section with no code, and place it on any template. To reuse the same section on other pages, see How to add a section to a page.

A note on tokens and metafields

Two upgrades make a section feel native and data-driven:

  • Design tokens. Rather than hard-coding #008060, pull from the theme's own color scheme so the section matches the store automatically. Dawn-based themes expose CSS custom properties like rgb(var(--color-foreground)) and provide a color_scheme setting type you can add to the schema. Referencing those means a merchant who re-brands the store updates your section for free.
  • Metafields. When a section should show store or product data — a spec table, a care guide, a badge — read it from a metafield instead of a text setting, e.g. {{ product.metafields.custom.care_guide }}. The content then lives with the product and stays in sync everywhere the section is used. Define the metafield under Settings → Custom data first.

Keep this section update-safe

Everything above writes the section into your theme files. That is the normal, documented way to build a section — but be clear-eyed about the trade-off: when you install a new version of the theme or switch themes, Shopify publishes a fresh copy of the theme's files and your feature-banner.liquid is not carried over. The section, and any settings merchants configured, can disappear.

Two ways to protect the work:

  1. Keep a disciplined workflow — track every custom file and re-apply it after each theme update. The method is in Update your theme without losing customizations.
  2. Render the section from an app instead of a theme file, via a Theme App Extension, so no theme update or swap can touch it.

If the section is something you rely on long-term, SectionGuard renders it from the app rather than your theme files — so it survives every theme update and swap, with the same in-editor configuration merchants already expect.