Building Reusable Sections in Shopify 2.0 Themes

Table of Contents
Big thanks to our contributors those make our blogs possible.

Our growing community of contributors bring their unique insights from around the world to power our blog. 

Introduction

Shopify 2.0 introduced a paradigm shift in theme development by making sections available on every page. Reusable sections empower merchants and developers to craft modular, drag-and-drop layouts without duplicating code. In this guide, you’ll learn how to design, develop, and deploy reusable sections—complete with customizable settings, dynamic blocks, and performance best practices. Whether you’re building a hero banner, a testimonials carousel, or a customizable feature grid, you’ll walk away with expert insights and code examples to streamline your workflow and supercharge your theme’s flexibility.

Understanding Shopify 2.0 Sections

Sections are self-contained Liquid templates that define markup, styles, and settings. In Shopify 2.0, sections live in both templates/ and sections/, but the real power lies in JSON-configured reusable sections under sections/. Key concepts:

  • Schema & Settings: Defines what merchants can customize (text, images, toggles).
  • Blocks: Repeatable sub-elements (e.g., slides in a slider).
  • Presets: Preconfigured settings that merchants can pick in the theme editor.
  • Dynamic Rendering: Sections can fetch store data (products, collections).

Analogy: Think of each section as a LEGO® brick: one brick can be customized (color, size) and snapped into countless builds (pages).

Prerequisites and Setup

Tools You’ll Need

  • Shopify Partner Account: Free dev stores for testing.
  • Shopify CLI: Scaffold and preview themes.
  • Code Editor: VS Code with Liquid plugins.
  • Git: Version control for safe rollbacks.

Initializing Your Theme

bashCopyEditnpm install -g @shopify/cli @shopify/theme
shopify login --store your-dev-store.myshopify.com
shopify theme init my-theme-2.0
cd my-theme-2.0
shopify theme serve

This spin-up gives you a 2.0-compatible starter with sections/, templates/, and config/.

Anatomy of a Reusable Section

File Structure

pgsqlCopyEditsections/
└── feature-grid.liquid
templates/
└── index.json
config/
└── settings_schema.json
  • sections/feature-grid.liquid: Contains HTML, Liquid, CSS classes, and schema.
  • templates/index.json: References sections by name and order.
  • settings_schema.json: Defines global theme settings (optional for section presets).

Defining the Section Schema

At the bottom of sections/feature-grid.liquid:

liquidCopyEdit{% schema %}
{
  "name": "Feature Grid",
  "max_blocks": 6,
  "blocks": [
    {
      "type": "feature",
      "name": "Feature Block",
      "settings": [
        {
          "type": "image_picker",
          "id": "icon",
          "label": "Icon Image"
        },
        {
          "type": "text",
          "id": "title",
          "label": "Title",
          "default": "Your Feature Title"
        },
        {
          "type": "textarea",
          "id": "description",
          "label": "Description",
          "default": "A brief description of this feature."
        }
      ]
    }
  ],
  "presets": [
    {
      "name": "Default feature grid",
      "category": "Custom"
    }
  ]
}
{% endschema %}
  • max_blocks: Limits how many feature cards merchants can add.
  • blocks: Defines each repeatable item.
  • presets: Makes “Default feature grid” available by default in new themes.

Building the Section Markup

Above the schema, craft your HTML and Liquid loops:

liquidCopyEdit<div class="feature-grid">
  {% if section.blocks.size > 0 %}
    <div class="feature-grid__wrapper">
      {% for block in section.blocks %}
        <div class="feature-grid__item">
          {% if block.settings.icon %}
            <img src="{{ block.settings.icon | img_url: '100x100' }}" alt="{{ block.settings.title }}">
          {% endif %}
          <h3>{{ block.settings.title }}</h3>
          <p>{{ block.settings.description }}</p>
        </div>
      {% endfor %}
    </div>
  {% else %}
    <p>Add up to {{ section.settings.max_blocks }} feature blocks.</p>
  {% endif %}
</div>
  • section.blocks: Iterates through every added block.
  • Graceful Fallback: Prompts merchants to add blocks if none exist.

Adding Styles and Responsiveness

In assets/component-feature-grid.css:

cssCopyEdit.feature-grid__wrapper {
  display: grid;
  grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
  gap: 1.5rem;
}

.feature-grid__item {
  text-align: center;
  padding: 1rem;
  border: 1px solid var(--color-border);
  border-radius: 8px;
}

Expert Tip: Use CSS custom properties (e.g., --color-border) so merchants can control colors via theme settings.

Include this stylesheet in your layout/theme.liquid head:

liquidCopyEdit{{ 'component-feature-grid.css' | asset_url | stylesheet_tag }}

Exposing Section Settings to Templates

Registering in JSON Template

In templates/index.json:

jsonCopyEdit{
  "sections": {
    "hero": {
      "type": "hero",
      "settings": {}
    },
    "features": {
      "type": "feature-grid",
      "settings": {}
    }
  },
  "order": ["hero", "features"]
}

This declares the order of reusable sections on the homepage.

Advanced Customization: Conditional Logic and Defaults

Conditional CSS Classes

Allow merchants to choose light or dark styles:

  1. Extend Schema with a select setting: jsonCopyEdit{ "type": "select", "id": "style_variant", "label": "Style Variant", "options": [ { "value": "light", "label": "Light" }, { "value": "dark", "label": "Dark" } ], "default": "light" }
  2. Apply in Markup: liquidCopyEdit{% assign variant = section.settings.style_variant %} <div class="feature-grid feature-grid--{{ variant }}"> ... </div>
  3. Add Modifiers in CSS: cssCopyEdit.feature-grid--dark .feature-grid__item { background-color: #333; color: #fff; }

Testing & Best Practices

Local Testing

  • Theme Serve: shopify theme serve for live reload.
  • Theme Editor: Ensure drag-and-drop works and settings appear.
  • Responsive Check: Toggle device toolbar in DevTools.

Performance & Maintenance

  • Limit Block Count: Prevent excessive DOM nodes (e.g., max_blocks: 6).
  • Lazy-Load Images: Add loading="lazy" to <img> tags.
  • Reuse Snippets: For repeated logic (e.g., image with caption), move into snippets/feature-block.liquid.
  • Schema Validation: Always test presets to ensure they load default blocks.

Pro Tip: Include placeholder images and text in your presets so merchants see a complete layout on first install.

Conclusion

Reusable sections in Shopify 2.0 unlock the full potential of modular, customizable storefronts. By defining clear schemas, crafting flexible markup, and leveraging settings and blocks, you can empower merchants to build unique pages without code. Remember to structure your CSS for adaptability, register sections in JSON templates, and follow performance best practices. With this approach, you’ll deliver themes that are both developer-friendly and merchant-proof—ready for any business to assemble, style, and scale.

Let's connect on TikTok

Join our newsletter to stay updated

Sydney Based Software Solutions Professional who is crafting exceptional systems and applications to solve a diverse range of problems for the past 10 years.

Share the Post

Related Posts