---
title: Block tag
description: Learn how to call reusable theme blocks directly from Liquid templates.
source_url:
  html: >-
    https://shopify.dev/docs/storefronts/themes/getting-started/developer-preview/block
  md: >-
    https://shopify.dev/docs/storefronts/themes/getting-started/developer-preview/block.md
---

# Block tag

**Developer preview:**

To use the `{% block %}` tag, select **Liquid July '26 changes** from the available [feature previews](https://shopify.dev/docs/api/feature-previews). Help shape this feature while it's in developer preview by sharing what's working and what needs work in the [Shopify developer community](https://community.shopify.dev/).

A block is a reusable piece of a page, with markup, behavior, accessibility attributes, and theme editor settings kept together in one Liquid file. These are the same [theme blocks](https://shopify.dev/docs/storefronts/themes/architecture/blocks) you already use. What's new is how you place them on a page: instead of only adding a block through the theme editor, a Liquid template can render one directly with `{% block %}`.

Use `{% block %}` the same way that [`{% render %}`](https://shopify.dev/docs/api/liquid/tags/render) renders a snippet: name the block file, pass any named parameters it accepts, and optionally provide body content. Because the template names each block, you can read a page's structure as a tree of blocks in the template itself. Page-specific content stays in the template that calls the block.

***

## Basic syntax

The block name maps to a file in `blocks/`. For example, `{% block 'container' %}` renders `blocks/container.liquid`.

A template composes its page by calling blocks. The following template puts a heading inside a `container` block:

## templates/index.liquid

```liquid
{% block 'container' %}
  <h1>Welcome</h1>
{% endblock %}
```

Everything between the opening and closing tags is the block's body content. The block file is written in Liquid, and it prints that body content with `{{ block.content }}`:

## blocks/container.liquid

```liquid
{% assign tag = tag | default: 'div' %}
<{{ tag }} class="{{ class }}">
  {{ block.content }}
</{{ tag }}>


{% schema %}
{
  "name": "t:blocks.container",
  "settings": []
}
{% endschema %}
```

The `{% schema %}` tag is where a block declares its theme editor settings, and this one has none yet. See [Authoring a block file](#authoring-a-block-file) for `{% schema %}` and `{% doc %}`.

***

## Passing parameters

Pass named parameters after the block name, like you do with `{% render %}`. The block's Liquid code decides what each one does.

```liquid
{% block 'container', tag: 'header', class: 'site-header' %}
  <h1>Page title</h1>
{% endblock %}
```

This call passes a `tag` and a `class`, which the block can use to choose its HTML element and add CSS classes. `class` has no special platform behavior, so your styling stays visible in the Liquid that renders the HTML.

### Schema settings

A block's `{% schema %}` defines its [theme editor settings](https://shopify.dev/docs/storefronts/themes/architecture/settings/input-settings), which the block reads as `block.settings.<id>`. A merchant usually sets these values in the theme editor. From a `{% block %}` call, you can set them directly with `block.settings.*` parameters, which is useful when the template already knows the value.

```liquid
{% block 'button', block.settings.variant: 'button-primary' %}
  Add to cart
{% endblock %}
```

This sets the block's `variant` setting to `button-primary`, the same value the block would otherwise read from the theme editor.

Pass named parameters and settings together when the template needs both:

```liquid
{% block 'product-card',
  class: 'featured-product',
  block.settings.product: product
%}
{% endblock %}
```

For how a block declares and reads settings, see [block schema](https://shopify.dev/docs/storefronts/themes/architecture/blocks/theme-blocks/schema).

### Arrays

A block parameter can take a literal array for a short list that lives in the template.

For a direct parameter, list the values inline:

```liquid
{% block 'badge-list',
  badges: ['New arrival', 'Low stock', 'Online only']
%}
{% endblock %}
```

The same works for a `block.settings.*` parameter that maps to a schema setting:

```liquid
{% block 'collection-list',
  block.settings.collections: [collections['summer'], collections['sale']]
%}
{% endblock %}
```

**Note:**

Inline literal arrays are specific to the `{% block %}` tag. Other tags, such as `{% render %}` and `{% partial %}`, don't accept an array written directly in the tag.

### Body content

The content between `{% block 'name' %}` and `{% endblock %}` is the block's body content, and the block prints it with `{{ block.content }}`.

Body content can be plain markup, other blocks, or both. For example, a product template passes a heading and a nested `button` block into a `container`:

## templates/product.liquid

```liquid
{% block 'container' %}
  <h1>{{ product.title }}</h1>
  {% block 'button', type: 'submit', class: 'button--full-width' %}
    Add to cart
  {% endblock %}
{% endblock %}
```

When a block only displays text or markup, pass it as body content instead of adding parameters like `title`, `body`, or `heading`. Add a parameter only when the block needs to do something with the value, like change how it renders or read the data you pass.

***

## Authoring a block file

A block file contains Liquid markup and can include the familiar `{% doc %}` and `{% schema %}` tags:

* Use [`{% doc %}`](https://shopify.dev/docs/storefronts/themes/tools/liquid-doc) to document the named parameters the block accepts and to show how to call it.
* Use [`{% schema %}`](https://shopify.dev/docs/storefronts/themes/architecture/blocks/theme-blocks/schema) for settings in the theme editor, such as appearance choices, resource pickers, and contextual component settings.

Use a parameter for a value the template controls, and a schema setting for a value a merchant controls. For example, the template sets the button's `type`, while a merchant picks its `variant` in the theme editor:

## blocks/button.liquid

```liquid
{% doc %}
  @param {string} [type] - HTML button type.
{% enddoc %}


<button type="{{ type }}" class="{{ block.settings.variant }}">
  {{ block.content }}
</button>


{% schema %}
{
  "name": "t:blocks.button",
  "settings": [
    {
      "type": "select",
      "id": "variant",
      "label": "t:settings.variant",
      "options": [
        {"value": "button-primary", "label": "t:options.primary"}
      ]
    }
  ]
}
{% endschema %}
```

Keep a block focused. Aim for six settings or fewer, and if it needs many more, split it into smaller blocks. Anything the template controls should be a parameter, not a setting.

When a value can come from either a parameter or a setting, you choose the order in the block's Liquid. For example, this button uses a `variant` parameter if the template passes one, then falls back to the `variant` setting, and finally a default:

```liquid
{% assign variant = variant | default: block.settings.variant | default: 'button-primary' %}


<button class="{{ variant }}">
  {{ block.content }}
</button>
```

***

## Choosing between block, content\_​for, and render

These tags all render reusable code. Which one you use comes down to who controls the page and what you're rendering.

* **`{% block %}`**: Use when the template controls the page. You name the block and pass it parameters and body content, so the whole composition stays in Liquid you can read top to bottom.
* **`{% content_for %}`**: Use when a merchant controls the page by adding and arranging blocks in the theme editor, which Shopify stores in a JSON template.
* **[`{% render %}`](https://shopify.dev/docs/api/liquid/tags/render)**: Use for a snippet in `snippets/`, for internal, repeated Liquid that has no theme editor settings.

***
