Skip to content

Blocks

Blocks are the parts of a section merchants add and reorder: slides of a slideshow, columns of a multicolumn section, the title, price and buy buttons of a product page.

Defined in the section’s schema and drawn by the section’s own loop:

{% for block in section.blocks %}
<div class="column" {{ block.shopify_attributes }}>
{%- case block.type -%}
{%- when 'image' -%}{{ block.settings.image | image_url: width: 800 | image_tag }}
{%- when 'text' -%}{{ block.settings.text }}
{%- endcase -%}
</div>
{% endfor %}
{% schema %}
{ "name": "Multicolumn", "blocks": [
{ "type": "image", "name": "Image", "settings": [{ "type": "image_picker", "id": "image", "label": "Image" }] },
{ "type": "text", "name": "Text", "settings": [{ "type": "richtext", "id": "text", "label": "Text" }] }
] }
{% endschema %}

Always output {{ block.shopify_attributes }} on the block’s outer element: the visual editor needs it to select the block.

A theme block is a file in blocks/ with its own schema. Many sections can use it, and blocks can hold other blocks.

blocks/heading.liquid
<h2 class="heading heading--{{ block.settings.size }}" {{ block.shopify_attributes }}>{{ block.settings.text }}</h2>
{% schema %}
{
"name": "Heading",
"settings": [
{ "type": "inline_richtext", "id": "text", "label": "Text", "default": "Heading" },
{ "type": "select", "id": "size", "label": "Size", "default": "md",
"options": [{ "value": "sm", "label": "Small" }, { "value": "md", "label": "Medium" }, { "value": "lg", "label": "Large" }] }
],
"presets": [{ "name": "Heading" }]
}
{% endschema %}

A section accepts theme blocks with { "type": "@theme" } (any of them) or by name ({ "type": "heading" }), and renders them with:

{% content_for 'blocks' %}

A theme block that holds blocks does the same: "blocks": [{ "type": "@theme" }] in its schema and {% content_for 'blocks' %} in its markup. Nesting stops at 8 levels.

A file whose name starts with _ (blocks/_card-media.liquid) is a private block: it isn’t offered for @theme, only to sections and blocks that name it.

A section can place a theme block itself, where merchants can edit its settings but not move or delete it:

{% content_for 'block', type: 'heading', id: 'title' %}

The id keeps its settings in the template’s JSON.

A product section hands its product to every block inside it, however deep:

sections/main-product.liquid
{% content_for 'blocks', closest.product: product %}
blocks/product-price.liquid
{%- assign product = closest.product | default: product -%}
<div class="price" {{ block.shopify_attributes }}>{{ product.price | money }}</div>

So one price block works on the product page, in a featured product section and in quick view. See closest.

Like sections, a block can set "capability": "wishlist" in its schema to render only while that store feature is on, and to be hidden from the editor while it’s off.

Was this page helpful?