Explore advanced Liquid, metafields, section schema, and JavaScript strategies for high-impact customisation in Shopify themes.
Outgrowing the default Shopify theme editor is inevitable. If you’re a developer looking to extend your theme’s flexibility, this guide covers advanced customisation patterns using Liquid, schema, metafields, and JavaScript enhancements.
1. Dynamic Section Rendering
Create conditional section blocks based on theme settings or context:
{% if section.settings.enable_hero %}
{% section 'hero' %}
{% endif %}
Use schemas to toggle logic via the editor:
2. Flexible Layouts with blocks
Leverage block types to enable modular layouts inside sections:
{% for block in section.blocks %}
{% case block.type %}
{% when 'image' %}
<img src="{{ block.settings.image | image_url }}">
{% when 'text' %}
<p>{{ block.settings.text }}</p>
{% endcase %}
{% endfor %}
Use limit and reorderable options in the schema for maximum flexibility.
3. Metafields for Structured Content
Replace hardcoded fields with dynamic product, collection, or page metafields.
{{ product.metafields.custom.warranty }}
Set up namespace + key structure in Shopify admin or via API:
- Namespace:
custom - Key:
warranty - Type:
single_line_text_field
4. Custom Schema Inputs
Use url, range, richtext, and color input types to enhance your settings UI:
Pair these with Tailwind or inline styles:
<section style="background: {{ section.settings.background }}">
5. Scoped JavaScript per Section
Avoid bloated global scripts. Attach scoped JS per section using:
<script src="{{ 'gallery.js' | asset_url }}" defer></script>
Or inline with section wrapping:
{% if section.id == 'gallery' %}
<script>
document.querySelectorAll('.gallery').forEach(initGallery)
</script>
{% endif %}
6. Data Attributes for JS Context
Embed Liquid data for JS logic:
<div data-product-title="{{ product.title }}" data-available="{{ product.available }}">
JS can then fetch:
const available = el.dataset.available === 'true';
7. Inline Logic for Custom Blocks
Use unless, cycle, and capture to reduce duplication:
{% capture banner_style %}
{% if section.settings.full_width %}full{% else %}contained{% endif %}
{% endcapture %}
Then reuse:
<div class="banner {{ banner_style }}">
Real-World Impact
In a bespoke Shopify build for a luxury brand:
- Used nested schema logic for conditionally rendering banners
- Product metafields drove dynamic upsells
- Scoped JS delivered interaction without global bloat