Skip to content

Liquid & Schema

{% comment %} Wrong — silently outputs nothing {% endcomment %}
<div class="{{ condition ? 'a' : 'b' }}">
{% comment %} Correct {% endcomment %}
<div class="{% if condition %}a{% else %}b{% endif %}">

Filters can’t span lines inside {% liquid %}

Section titled “Filters can’t span lines inside {% liquid %}”
{% comment %} Broken — syntax error {% endcomment %}
{% liquid
assign data = '{'
| append: '"key":'
%}
{% comment %} Fine — individual assign tag {% endcomment %}
{% assign data = '{'
| append: '"key":'
%}
{% comment %} Also fine — single line inside a liquid block {% endcomment %}
{% liquid
assign data = '{' | append: '"key":'
%}

This is a real source of silent bugs:

{% comment %} The filter is IGNORED — visited is passed unchanged {% endcomment %}
{% render 'tree', visited: visited | append: id %}
{% comment %} Correct — build the value first {% endcomment %}
{% assign next_visited = visited | append: id %}
{% render 'tree', visited: next_visited %}

render also creates an isolated scope — a snippet can’t hand variables back. When you need a value out of one, echo a delimited string and capture it:

{%- capture result -%}{%- render 'tag-style-map', tag: tag -%}{%- endcapture -%}
{%- assign parts = result | split: '|' -%}

Hide settings that don’t apply, rather than letting merchants set values that do nothing:

{
"type": "color",
"id": "badge_color",
"label": "t:blocks.my-block.settings.badge_color.label",
"visible_if": "{{ block.settings.badge_label != blank }}"
}

Use section.settings.* in sections, block.settings.* in blocks. The double braces are required.

"default": "<p>Text in paragraph tags</p>"

Bare text fails validation. Allowed top-level tags: <p>, <h1><h6>, <ul>, <ol>.

A block won’t appear in the customizer’s picker without one, even a bare one:

"presets": [{ "name": "My Block" }]

Every schema label, info string and select option needs a key in locales/en.default.schema.json.

Run both before committing:

Terminal window
npx shopify theme check

The Shopify MCP validate_theme tool catches schema issues that theme check misses. The target is zero errors — warnings are triaged separately.