---
url: https://docs.youcan.shop/themes/theme-blocks.md
---
# Theme blocks
A theme block is a block with its own Liquid file in the `blocks` directory. You can use the same theme block in many sections, and you can put blocks inside a theme block.
Sellers add, remove, reorder and edit theme blocks in the theme editor, the same as [section blocks](/themes/blocks).
## Location
Save each theme block as a Liquid file in the `blocks` directory. The file name, without the `.liquid` extension, is the block type.
```bash
└── theme
├── blocks
│ ├── group.liquid
│ ├── text.liquid
│ ├── _card-title.liquid
│ ...
├── sections
...
```
A block type that starts with `_` is private. A private block can only be added where its type is listed in the parent schema. See [Accepting theme blocks](#accepting-theme-blocks).
## Block file
A block file has Liquid markup and a `{% schema %}` tag.
```liquid
{{ block.settings.text }}
{% schema %}
{
"name": "Text",
"settings": [
{ "type": "text", "id": "text", "label": "Text", "default": "Add your text" }
],
"presets": [
{ "name": "Text", "category": "Basic" }
]
}
{% endschema %}
```
| Property | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `name` | `string` | Yes | The block name shown in the theme editor. Can be a `t:` locale key. Max 255 characters. |
| `tag` | `string` | `null` | No | The HTML element the block is wrapped in. Defaults to `div`. Max 50 characters. Use `null` to render the block without a wrapper. |
| `class` | `string` | No | A class added to the wrapper element. Max 255 characters. |
| `settings` | `array` | No | [Setting](/themes/settings/overview) definitions for the block, read through `block.settings`. |
| `blocks` | `array` | No | The block types allowed in this block. Each entry has only a `type`. See [Accepting theme blocks](#accepting-theme-blocks). |
| `presets` | `array` | No | The ready-made versions of the block that sellers can pick. See [Presets](#presets). |
### Wrapper
Each theme block is rendered inside a wrapper element:
```html
...
```
For a nested block, the `id` also contains the IDs of all parent blocks between the section ID and the block ID.
When `tag` is `null`, the block is rendered without a wrapper. Add {{ block.youcan\_attributes }} to the root element of the block. These attributes are used by the theme editor to select the block in the preview. They are printed only in the theme editor.
```liquid
{{ block.settings.heading }}
{% schema %}
{
"name": "Heading",
"tag": null,
"settings": [
{ "type": "text", "id": "heading", "label": "Heading" }
]
}
{% endschema %}
```
## Accepting theme blocks
You set the blocks allowed in a section or a theme block in the `blocks` array of its schema.
| Entry | Allows |
| ----- | ------- |
| `{ "type": "@theme" }` | All theme blocks whose type does not start with `_`. |
| `{ "type": "text" }` | The theme block `blocks/text.liquid`. Use the type of a private block to allow it. |
| `{ "type": "@app" }` | The [app blocks](/apps/theme_extension/overview) of the apps the seller installed. |
```liquid
{% schema %}
{
"name": "Card",
"blocks": [
{ "type": "@theme" },
{ "type": "_card-title" },
{ "type": "@app" }
]
}
{% endschema %}
```
A section schema can list theme blocks or define its own [section blocks](/themes/sections/section-schema#blocks), but not both. A section schema that has both is rejected when the theme is saved.
Theme blocks can be nested up to 8 levels deep.
## Rendering theme blocks
Render the blocks of a section or a theme block with the [`content_for`](/themes/tags/content_for) tag.
```liquid
{% content_for 'blocks' %}
```
The blocks are rendered in the order of `order`. Disabled blocks are not rendered.
Inside a block file, you get:
* `block.id`: The block ID.
* `block.type`: The block type.
* `block.settings`: The setting values of the block.
* `block.youcan_attributes`: The attributes used to select the block in the theme editor. Printed only in the theme editor.
* `section`: The section that holds the block.
* `closest.product`, `closest.collection`, `closest.article` and `closest.blog`: The nearest resource of that type, from the template or from a parent block.
### Static blocks
A static block is a block that the developer places in the markup. Sellers can edit its settings, but they cannot move or remove it.
Render a static block with `content_for 'block'`, a `type` and an `id`:
```liquid
{% content_for 'block', type: '_card-title', id: 'title' %}
```
The `id` must be unique inside its parent. The setting values of a static block are stored in the template, under the parent, with `"static": true`. When no values are stored, the block is rendered with its default values.
You can pass more values to a static block. They are available as variables inside the block file. Use a value whose name starts with `closest.` to set the matching `closest` object.
```liquid
{% content_for 'block', type: 'price', id: 'price', size: 'large', closest.product: featured_product %}
```
## Presets
A preset is a ready-made version of a block. Sellers pick a preset in the theme editor to add the block. A theme block without presets is not shown in the block picker. You can still use it as a static block or in a preset of another block.
| Property | Type | Required | Description |
| -------- | ---- | -------- | ----------- |
| `name` | `string` | Yes | The preset name shown in the theme editor. Can be a `t:` locale key. |
| `category` | `string` | No | The group the preset is listed under in the theme editor. Can be a `t:` locale key. |
| `settings` | `object` | No | Setting values for the block, keyed by setting `id`. Settings that are not in the preset get their default value. |
| `blocks` | `array` | `object` | No | The child blocks added with the preset. Each child has a `type`, and can have `settings`, `blocks`, `static` and `id`. |
| `block_order` | `array` | No | The order of the child blocks, when `blocks` is an object. |
```json
"presets": [
{
"name": "Card",
"category": "Layout",
"settings": { "padding": 24 },
"blocks": [
{ "type": "_card-title", "id": "title", "static": true },
{ "type": "text", "settings": { "text": "Add a description" } }
]
}
]
```
A child with `"static": true` must have the same `id` as the matching `content_for 'block'` tag.
## Template data
Theme blocks are stored in the JSON template or [section group](/themes/sections/section-groups), inside the section that holds them. A theme block with child blocks has its own `blocks` and `order`.
```json
"main": {
"type": "featured",
"blocks": {
"card": {
"type": "card",
"blocks": {
"title": { "type": "_card-title", "static": true, "settings": { "text": "New arrivals" } },
"text_1": { "type": "text", "settings": { "text": "Shop the collection" } }
},
"order": ["text_1"]
}
},
"order": ["card"]
}
```
See [Block object](/themes/templates/json-templates#block-object) for all properties.
The data of each block is validated against its schema. A template with an unknown block type, or a block type that is not allowed in its parent, cannot be saved.