Most stores reach the point where the theme editor’s defaults don’t cover what the marketing team wants. This guide covers the patterns that give merchants more control without breaking the theme: section settings, blocks, metafields, schema inputs and JavaScript scoped to each section.
1. Let the editor control what renders
In Online Store 2.0 themes, merchants add, remove and reorder sections in the theme editor, so a section doesn’t render other sections. Inside a section, use settings to switch content on and off:
{% if section.settings.show_banner %}
<div class="promo-banner">{{ section.settings.banner_text }}</div>
{% endif %}
{% schema %}
{
"name": "Promo",
"settings": [
{ "type": "checkbox", "id": "show_banner", "label": "Show banner", "default": true },
{ "type": "text", "id": "banner_text", "label": "Banner text" }
]
}
{% endschema %}
2. Flexible layouts with blocks
Use block types to build modular layouts inside sections:
{% for block in section.blocks %}
<div {{ block.shopify_attributes }}>
{% case block.type %}
{% when 'image' %}
{{ block.settings.image | image_url: width: 1200 | image_tag }}
{% when 'text' %}
<p>{{ block.settings.text }}</p>
{% endcase %}
</div>
{% endfor %}
block.shopify_attributes lets the theme editor find and select each block. Use max_blocks on the section and limit on a block type to stop a layout being stretched past what the design can take.
3. Metafields for structured content
Replace hard-coded text with product, collection or page metafields:
{{ product.metafields.custom.warranty.value }}
Create a metafield definition in Settings > Custom data, or through the API:
- Namespace:
custom - Key:
warranty - Type:
single_line_text_field
A definition gives the field a proper input in the admin and lets you connect it to theme settings without code.
4. Custom schema inputs
Setting types such as url, range, richtext and color give merchants the right input for each value:
{ "type": "color", "id": "background", "label": "Background colour", "default": "#ffffff" },
{ "type": "range", "id": "padding", "label": "Padding", "min": 0, "max": 80, "step": 4, "unit": "px", "default": 40 }
Use them in the section’s markup:
<section style="background: {{ section.settings.background }}; padding-block: {{ section.settings.padding }}px">
5. Scoped JavaScript per section
Don’t put every section’s code in one global script. Load a section’s script from inside the section file, so it only arrives on pages that use that section:
<script src="{{ 'gallery.js' | asset_url }}" defer></script>
Don’t test section.id against a fixed name. In JSON templates, section IDs are generated, so the check never matches.
The theme editor re-renders a section when a merchant changes its settings. Listen for shopify:section:load and set the section up again, or it stops working in the editor:
document.addEventListener('shopify:section:load', (event) => {
event.target.querySelectorAll('.gallery').forEach(initGallery);
});
6. Pass data to JavaScript safely
Escape anything you put in an attribute:
<div data-product-title="{{ product.title | escape }}" data-available="{{ product.available }}">
const available = el.dataset.available === 'true';
For more than a couple of values, output JSON once instead:
<script type="application/json" id="product-data">{{ product | json }}</script>
7. Inline logic for custom blocks
Use assign, unless and capture to avoid repeating markup. Trim whitespace inside capture, or the class name picks up stray spaces and line breaks:
{%- capture banner_style -%}
{%- if section.settings.full_width -%}full{%- else -%}contained{%- endif -%}
{%- endcapture -%}
Then reuse:
<div class="banner {{ banner_style }}">
A real example
On a Shopify Plus rebuild for a UK jeweller, the theme was built from modular sections and reusable templates. That gave the marketing team control of page layouts and seasonal campaigns without waiting for a developer.
Related reading
When a theme can’t do what the marketing team asks of it, these are the first changes I’d make as your Shopify developer.
Published , updated .
Part 6 of Shopify Essentials.