Theme blocks support the `{% schema %}` Liquid tag. This tag is used to define the following block attributes and settings: - [`name`](#name) - [`settings`](#settings) - [`blocks`](#blocks) - [`presets`](#presets) - [`tag`](#tag) - [`class`](#class) These attributes and settings enable different customization options and preconfigurations of the block inside the theme editor. The following is an example of a block schema that opts-in to supporting nested blocks with its `block` attribute, defines some background-related `settings`, and assembles different variations of those settings with its `presets` attribute: ```json {% schema %} { "name": "Slide", "blocks": [{"type": "@app"}, {"type": "@theme"}], "settings": [ { "type": "image_picker", "id": "image", "label": "Background image" }, { "type": "color_background", "id": "background", "label": "Background color" } ], "presets": [ { "name": "Slide", "settings": { "background": "#000000" }, "blocks": [ { "type": "text", "settings": { "text": "This is a slide!" } } ] } ] } {% endschema %} ``` Each block can have only a single `{% schema %}` tag, which must contain only valid JSON and can only use the attributes listed below. The schema tag can be placed anywhere within the block file, but it can’t be nested inside another Liquid tag. It doesn’t output its contents, or render any Liquid included inside it. > Caution > Having more than one `{% schema %}` tag, or placing it inside another Liquid tag, will result in an error. ## name The `name` attribute determines the block title that's shown in the theme editor. For example, the following schema returns the following output: ```json {% schema %} { "name": "Slide" } {% endschema %} ```  ### Showing dynamic block titles in the theme editor In specific cases, the theme editor can display an input setting value as the title of a block in the theme editor sidebar. This can help merchants to identify and rearrange blocks in a section. The theme editor checks [the `id` values](/docs/storefronts/themes/architecture/settings/input-settings#standard-attributes) of the settings in a block to determine the best one to use for the block title. The theme editor uses settings with the following `id` values, in the following order of precedence: 1. `heading` 2. `title` 3. `text` If a setting with a matching `id` value doesn't exist, then the block name is used as the title. For example, the following block with a setting `id` of `text` displays in the sidebar with the title `Welcome to our store`. ```json { "name": "Text", "settings": [ { "type": "text", "id": "text", "default": "Welcome to our store", "label": "Content" } ] } ``` ## settings You can create block-specific [settings](/docs/storefronts/themes/architecture/settings/input-settings) to enable merchants to customize the block with the `settings` object: ```json {% schema %} { "name": "Slide", "settings": [ { "type": "image_picker", "id": "image", "label": "Background image" }, { "type": "color_background", "id": "background", "label": "Background color" } ] } {% endschema %} ``` > Caution: > All block setting IDs must be unique within each block. Having duplicate IDs within a block throws an error. ### Accessing block settings Block settings can be accessed through the [`block` object](/docs/api/liquid/objects/block#block-settings). Refer to [Access settings](/docs/storefronts/themes/architecture/settings#access-settings) to learn more. ## blocks Theme blocks can accept other app and theme blocks as children using the `blocks` attribute of their schema: ```json {% schema %} { "name": "Slide", "blocks": [{"type": "@app"}, {"type": "@theme"}] } {% endschema %} ``` The `"@app"` type denotes that this block accepts app blocks. [App blocks](/docs/storefronts/themes/architecture/blocks/app-blocks) enable app developers to create blocks for merchants to add app content to their theme without having to directly edit theme code. The `"@theme"` type denotes that this block is compatible with other theme-defined blocks that live in the `/blocks` folder of the theme. Theme blocks can also be made individually accessible by explicitly referencing them. ```json {% schema %} { "name": "Slideshow", "blocks": [{"type": "@app"}, {"type": "slide"}] } {% endschema %} ``` > Note > Unlike sections, which can define blocks locally using the blocks attribute of their schema, Theme blocks can't define local blocks in the `blocks` attribute of their schema. ### Rendering nested blocks You can render a block's child blocks by using the `{% content_for 'blocks' %}` Liquid tag: ```liquid
``` In the example above, each block's content is outputted by the `{% content_for 'blocks' %}` tag in the order stored in the [JSON template](/docs/storefronts/themes/architecture/templates/json-templates). > Tip > Theme blocks can be nested up to 8 levels deep, excluding the section level. ## presets Presets are predefined block configurations that merchants can select when adding blocks to a [JSON template](/docs/storefronts/themes/architecture/templates/json-templates). Presets help you quickly provide merchants with different layouts and use cases by adjusting block settings. Additionally, presets of a block may reference other child blocks and assemble them in any number of configurations. Presets appear in the **Add block** picker as follows:  | Number | Description | | --- | --- | | 1 | Presets appear alphabetically based on their `name` attribute. | | 2 | Presets can optionally be grouped into collapsible categories using the `category` attribute. | | 3 | Uncategorized presets are always displayed first. | Block presets have the following attributes: | Attribute | Description | Required | | --- | --- | --- | | `name` | The preset name displayed in the theme editor's **Add block** picker and sidebar, and is persisted in the JSON template when you add a block. | Yes | | `category` | Groups related presets together in the theme editor's **Add block** picker. | No | | `settings` | Default values for settings you want to pre-populate. Each entry includes the setting name and its value. | No | | `blocks` | Default blocks included in the preset. Each block entry must include a `type` attribute matching the block type, and a `settings` object formatted similarly to the `settings` attribute above.