Shopify Essentials: Advanced Customisation Techniques in Shopify Themes

10 minute read Shopify Essentials · Part 7

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