A theme app extension is a bundle of app blocks, app embed blocks, assets, and snippets. ## File structure When you [create a theme app extension](/docs/apps/build/online-store/theme-app-extensions/build), Shopify adds the following `theme-app-extension` directory and subdirectories to your app: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="Theme app extension file structure"></script> <script type="text/plain" data-language="file" data-title="Newly-generated extension"> └── extensions └── my-theme-app-extension ├── assets ├── blocks ├── snippets ├── locales ├── package.json └── shopify.extension.toml </script> <script type="text/plain" data-language="file" data-title="Populated"> └── extensions └── my-theme-app-extension ├── assets │ ├── image.jpg │ ├── icon.svg │ ├── app-block.js │ ├── app-block.css │ ├── app-embed-block.js │ └── app-embed-block.css ├── blocks │ ├── app-block.liquid │ └── app-embed-block.liquid ├── snippets │ ├── app-block-snippet.liquid │ └── app-embed-block-snippet.liquid ├── locales | ├── en.default.json | ├── en.default.schema.json | ├── fr.json | └── fr.schema.json ├── package.json └── shopify.extension.toml </script> </div> </p> <table> <caption>Theme app extension subdirectory descriptions</caption> <tr> <th scope="col">Subdirectory</th> <th scope="col">Description</th> </tr> <tr> <td><code>assets</code></td> <td><p>Contains CSS, JavaScript, and other static app content that gets injected into themes.</p> <p>Apps can load <a href="/docs/storefronts/themes/architecture#assets">assets</a> using either the <code>JavaScript</code> and <code>stylesheet</code> <a href="#schema">schema attributes</a> or from the <code><a href="/docs/api/liquid/filters/asset_url">asset_url</a></code> and <code><a href="/docs/api/liquid/filters/asset_img_url">asset_img_url</a></code> Liquid URL filters.</p></td> </tr> <tr> <td><code>blocks</code></td> <td>Contains <a href="#app-blocks-for-themes">app blocks for themes</a> and <a href="#app-embed-blocks">app embed block</a> Liquid files.</td> </tr> <tr> <td><code>snippets</code></td> <td>Contains Liquid <a href="/docs/storefronts/themes/architecture#snippets">snippet</a> files for the theme app extension, which are bits of code that you can reference in other app blocks and app embed blocks.</td> </tr> <tr> <td><code>locales</code></td> <td> <p>Contains JSON locale files to host merchant-facing and customer-facing translations. These files are similar to <a href="/docs/storefronts/themes/architecture/locales">theme locale files</a> in their schema and usage. You can include the following file types:</p> <ul> <li><a href="/docs/storefronts/themes/architecture/locales/schema-locale-files">Schema locale files</a>: Contains merchant-facing translations. Use these files to translate the settings that appear in the theme editor.</li> <li><a href="/docs/storefronts/themes/architecture/locales/storefront-locale-files">Storefront locale files</a>: Contains customer-facing translations. Use these files to translate the text that appears in the storefront when your app block or app embed block is rendered.</li> </ul> <p><b>Note:</b> Merchants can't edit the strings in theme app extension storefront locale files.</p> </td> </tr> <tr> <td><code>shopify.extension.toml</code></td> <td> <p>A configuration file containing basic app configuration settings, including the extension name and type (<code>theme</code>). </td> </tr> </table> ## App blocks for themes Apps that inject inline content on a page extend themes using app blocks. Merchants can add app blocks to a compatible theme section, or as [wrapped](#examples-of-app-blocks-in-a-theme) app blocks that are added at the section level. Create an app block by setting the `target` in the schema to `section`. By default, themes don't include app blocks after an app is installed. Merchants need to add the app blocks to the theme from the **Apps** section of the [theme editor](/docs/storefronts/themes/tools/online-editor). > Tip: > [Build app blocks responsively](https://www.shopify.com/partners/blog/responsive-app-blocks), so that they can adapt to the size of the sections to which they're added. Use app blocks for the following types of apps: * Apps that you want to automatically point to dynamic sources, such as product reviews apps and star ratings apps. * Apps that merchants might want to reposition on a page. * Apps that should span the full width of a page. ### App block support in themes For app blocks to function, a theme must contain the following: * [JSON templates](/docs/storefronts/themes/architecture/templates/json-templates). * Sections that [support](/docs/storefronts/themes/architecture/blocks/app-blocks#supporting-app-blocks) and [render](/docs/storefronts/themes/architecture/blocks/app-blocks#render-app-blocks) blocks of type `@app`. Refer to Dawn's [main product section](https://github.com/Shopify/dawn/blob/main/sections/main-product.liquid) for an example implementation. You can [verify](/docs/apps/build/online-store/verify-support) whether a theme supports app blocks . ### Example app block The following example creates a `span` element with a `style` attribute. The `style` value (`color: {{ block.settings.color }}`) searches inside of `schema` for a `settings` key, and then searches for a `color` key, which contains the `"default": "#000000"` value. This value then populates the `style` attribute with the default color `#000000`, which renders the `App blocks let you build powerful integrations with online store themes!` text in black. <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="Example app block"></script> <script type="text/plain" data-language="liquid"> <span style="color: {{ block.settings.color }}"> App blocks let you build powerful integrations with online store themes. </span> {% render "app_snippet" %} {% schema %} { "name": "Hello World", "target": "section", "enabled_on": { "templates": ["index"] }, "stylesheet": "app.css", "javascript": "app.js", "settings": [ { "label": "Color", "id": "color", "type": "color", "default": "#000000" } ] } {% endschema %} </script> </div> </p> > Tip: > For a more complex example, refer to Shopify's [product reviews app](https://github.com/Shopify/product-reviews-sample-app). ### Examples of app blocks in a theme The following is an example of an app block added to a section: <div style="text-align: center"><img src="/assets/apps/app-block.png" alt="An example of an app block added to a section. The section is beside a product image and is for a product star ratings app block." width="50%"></div> The following is an example of a wrapped app block: <div style="text-align: center"><img src="/assets/apps/app-block-fw.png" alt="An example of an app block added as a section and wrapped to span the full width of the page. The section is below product details and is for a customer review comments app block." width="50%"></div> ### Benefits of app blocks App blocks are flexible. Merchants can use the theme editor to add, remove, and reorder app blocks at the section level for easy customization. An app block can use [`autofill` resource settings](#autofill) to automatically point to dynamic sources and ensure that content remains in sync with its parent section. For example, an app block on the **Products** page can point to a dynamic source to show data for different products as they display on the page. ## App embed blocks Apps that don't have a UI component, or that add floating or overlaid elements, extend themes using app embed blocks. Shopify renders and injects app embed blocks before HTML `</head>` and `</body>` closing tags. Create an app embed block by setting the `target` in the schema to either `compliance_head`, `head`, or `body`. App embed blocks with `compliance_head` will be included first and should be used only when necessary, for example in cookie consent banners. By default, app embed blocks are deactivated after an app is installed. Merchants need to activate app embed blocks in the theme editor, from **Theme Settings** > **App embeds**. However, your app can provide merchants with a [deep link](#deep-linking), post installation, to activate an app embed block automatically. Use app embed blocks for the following types of apps: * Apps that provide a floating or overlaid component to a page, such as chat bubble apps and product image badge apps. * Apps that add SEO meta tags, analytics, or tracking pixels. App embed blocks are supported in vintage and in Online Store 2.0 themes, because they don't rely on sections or JSON templates. However, app embed blocks can't point to dynamic sources, because these blocks only have access to the Global Liquid scope for the page on which they're rendered. ### Example app embed block code > Tip: > For a more complex example, refer to our [getting started sample code](https://github.com/Shopify/theme-extension-getting-started). <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="Example app embed block"></script> <script type="text/plain" data-language="liquid"> <div style="position: fixed; bottom: 0; right: 0"> {{ "kitten.jpg" | asset_url | img_tag }} </div> {% schema %} { "name": "App Embed", "target": "body", "settings": [] } {% endschema %} </script> </div> </p> ### Example of an app embed block in a theme <div style="text-align: center"><img src="/assets/apps/app-embed-block.png" alt="An example of an app embed block injected into a theme's closing HTML body tag. The app provides a floating element on the page and is for a chat bubble app embed block" width="50%"></div> ### Benefits of app embed blocks App embed blocks are supported in vintage and Online Store 2.0 themes. This means any merchant can use your app without you needing to maintain two installation paths: one for vintage themes and one for Online Store 2.0 themes. After installation, merchants can use the theme code editor to configure app embed block settings for a more customized experience. App embed blocks allow you to only load scripts on specific pages, which isn't possible with the [`ScriptTag`](/docs/api/admin-graphql/latest/objects/ScriptTag) object. Loading scripts on specific pages minimizes your app's performance impact by limiting it to only the pages where it's needed. ## Conditional app blocks You can control the visibility of an app block or app embed block based on a custom condition. For example, you might want to limit content based on plan tier, or geographic location. The condition can be included in the block's [schema](#schema) with the `available_if` attribute, and the state of the condition is stored in an [app-data metafield](/docs/apps/build/custom-data/metafields/use-app-data-metafields). The metafield can be accessed through the Liquid [`app` object](/docs/api/liquid/objects/app). > Note: > The app metafield must be a `boolean` type metafield. For example, if you had an app metafield with the namespace of `conditional` and key of `block1`, then you might use the following schema: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="Conditional app block example"></script> <script type="text/plain" data-language="liquid"> {% schema %} { "name": "Conditional App block", "target": "section", "stylesheet": "app.css", "javascript": "app.js", "available_if": "{{ app.metafields.conditional.block1 }}", "settings": [ { "label": "Colour", "id": "colour", "type": "color", "default": "#000000" } ] } {% endschema %} </script> </div> </p> ## Schema The schema for app blocks and app embed blocks is similar to the [theme section schema](/docs/storefronts/themes/architecture/sections/section-schema). It supports the following attributes, some of which are unique to app blocks and app embed blocks: <table> <caption>Schema attributes</caption> <tr> <th scope="col">Attribute</th> <th scope="col">Description</th> <th>Required</th> </tr> <tr> <td><code>name</code></td> <td>The title in the theme editor for the app block or app embed block.<br/><br/>Keep app block and app embed block names under 25 characters so they fit in the theme editor sidebar.<br/><br/>Don't include the title of your app in the name of the block. The title of your app displays below the name of the app block or app embed block in app block pickers, the app embeds panel, and the app details panel.</td> <td>Yes</td> </tr> <tr> <td><code>target</code></td> <td><p>Where the block is located. The possible values are <code>section</code>, <code>head</code>, <code>compliance_head</code>, and <code>body</code>.</p> <p>The value for app blocks is <code>section</code>. The values for app embed blocks are <code>head</code>, <code>compliance_head</code>, and <code>body</code>. </td> <td>Yes</td> </tr> <tr> <td><code>JavaScript</code></td> <td><p>A JavaScript file to load from the <code>assets</code> subdirectory.</p> <p>If the block is present on the page, then you can load this file automatically by adding a <code><script async></code> tag in the <code><head></code> section of the page.</p> <p>If a merchant adds multiple app blocks or app embed blocks that reference the same JavaScript file to a page, then the file is only included once when the page is loaded.</p> </td> <td>No</td> </tr> <tr> <td><code>stylesheet</code></td> <td><p>A CSS file to load from the <code>assets</code> subdirectory.</p> <p>If the block is present on the page, then you can load this file automatically by adding a <code><link rel="stylesheet"></code> tag in the <code><head></code> section of the page.</p> <p>If a merchant adds multiple app blocks or app embed blocks that reference the same stylesheet file to a page, then the file is only included once when the page is loaded.</p> </td> <td>No</td> </tr> <tr> <td><code>enabled_on</code></td> <td><p>Limit an app block to specific templates and section groups, or limit an app embed block to specific templates.</p> <p>Refer to <a href="/docs/storefronts/themes/architecture/sections/section-schema#enabled_on">theme section schema</a> for more details.</p> <p>App blocks and app embed blocks can't be rendered on <a href="#restrictions">checkout step pages</a>.</p> <p>You can use only one of <code>enabled_on</code> or <code>disabled_on</code>.</p> </td> <td>No</td> </tr> <tr> <td><code>disabled_on</code></td> <td><p>Prevent app block from being used in specific templates and section groups, or prevent an app embed block from being used in specific templates.</p> <p>Refer to <a href="/docs/storefronts/themes/architecture/sections/section-schema#disabled_on">theme section schema</a> for more details.</p> <p>App blocks and app embed blocks can't be rendered on <a href="#restrictions">checkout step pages</a>.</p> <p>You can use only one of <code>enabled_on</code> or <code>disabled_on</code>.</p> </td> <td>No</td> </tr> <tr> <td><code>class</code></td> <td><p>Additional CSS classes to be included in the wrapping tag element, similar to <a href="/docs/storefronts/themes/architecture/sections/section-schema#class">theme section classes</a>.</p> <p>Theme app extensions will always include the <code>shopify-block</code> class.</p> </td> <td>No</td> </tr> <tr> <td><code>tag</code></td> <td><p>If set, then a <a href="/docs/storefronts/themes/architecture/sections/section-schema#tag">tag</a> wraps the block's output. If not set, then the output is wrapped in a <code>div</code>.</p> </td> <td>No<a id="schema-settings"></td> </tr> <tr> <td><code>settings</code></td> <td><p><a href="/docs/storefronts/themes/architecture/settings">Settings</a> that you provide to the merchant for customizing the app block or app embed block. These settings appear in the theme editor when the block is selected. Setting values can be <a href="/docs/storefronts/themes/architecture/settings#access-settings">accessed</a> using the <a href="/docs/api/liquid/objects/block#block-settings">settings</a> Liquid object.</p> </td> <td>No</td> </tr> <tr> <td><code>default</code></td> <td><p>A default setting configuration for the block. Refer to the <a href="/docs/storefronts/themes/architecture/sections/section-schema#default">section schema</a> for an example.</p> </td> <td>No</td> </tr> <tr> <td><code>available_if</code></td> <td> <p>Determines whether the block will be rendered on the storefront and visible in the theme editor.</p> <p>The value must be a reference to an <a href="/docs/api/admin-graphql/latest/objects/AppInstallation#field-appinstallation-metafield">app-data metafield</a> value. If the value of the app-data metafield returns true, then the block is rendered and available in the theme editor.</p> <p>Refer to <a href="#conditional-app-blocks">Conditional app blocks</a> for an example.</p> </td> <td>No</td> </tr> </table> ## Recommendations Review the following recommendations for building theme app extensions: * [Autofill](#autofill) * [Deep linking](#deep-linking) * [Performance](#performance) * [Theme editor compatibility](#theme-editor-compatibility) * [Detecting app blocks and app embed blocks](#detecting-app-blocks-and-app-embed-blocks) ### Autofill > Note: > This feature is only supported for resource settings in app blocks. `autofill` is an app block setting that's automatically set to [dynamic sources](/docs/storefronts/themes/architecture/settings/dynamic-sources) when merchants add an app block to a section. ``` App blocks can include settings in the `settings` schema object, like [sections](/docs/storefronts/themes/architecture/sections/section-schema#settings) do. You can give [resource settings](/docs/storefronts/themes/architecture/settings/input-settings#specialized-input-settings) an additional `autofill` attribute. `autofill` indicates that Shopify will determine the setting value automatically when a merchant adds the app block to a section. `autofill` setting values will be set to one of the following sources: * A dynamic source pointing to the parent section's resource setting of the same type. * A dynamic source pointing to the template's global resource. #### Autofill example A featured product section will have a setting of type `product`, which allows a merchant to choose which product to display as featured. An app block that has a `product` setting with `autofill` set will automatically use the featured product. In the following example, `block.settings.product` will use the section's `product` setting: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="Autofill example"></script> <script type="text/plain" data-language="liquid"> {{ block.settings.product.handle }} {% schema %} { ... "settings": [ { "type": "product", "id": "product", "label": "Product", "autofill": true } ], ... } {% endschema %} </script> </div> </p> ### Deep linking Post-installation, your app can provide deep links to help merchants add app blocks or activate app embed blocks directly in a theme. If a merchant clicks a deep link, then they're taken to the theme editor to preview the app block or app embed block before saving. Deep linking simplifies your app's installation because merchants won't need to navigate to the theme editor, find the block, and then act on it. Instead, your app does the work for them. Merchants can preview the block before saving and have more control over what they include in their online store. #### App block deep linking You can implement a deep link to add an app block to the following locations: * Any JSON template. For example, the `Default product` template. * A header, footer, or aside section group. For example, the `Header` section group. * Any main section that supports app blocks. For example, the `main-product` section. * A specific section that supports app blocks by **targeting its ID**. For example, the `Newsletter` section on the `index.json` template. After you add the app block in the theme editor, a coach mark helps the merchant move forward with next steps: <div style="text-align: center"><img src="/assets/apps/coachmark.png" alt="An example of an app block added to a section. The section is beside a product image and is for a product star ratings app block." width="100%"></div> > Note: > You can deep link only to sections that support app blocks. Additionally, you can add only one app block at a time with a deep link. #### App block deep link query parameters <table> <caption>App block deep link URL query parameters</caption> <tr> <th scope="col">Query parameter</th> <th scope="col">Description</th> </tr> <tr> <td><code>{template}</code></td> <td><p>The JSON template to which the app block should be added. If not set, then Shopify will default to the index.json template.</p> </td> </tr> <tr> <td><code>{uuid}</code></td> <td><p>The ID of the theme app extension.</p> <p>Retrieve the <code>SHOPIFY_{YOUR_EXTENSION_NAME}_ID</code> value from your project's <code>.env</code> file. This file is only available after you run the <code>deploy</code> command for the first time.</p> </td> </tr> <td><code>{handle}</code></td> <td><p>The filename of the block's Liquid file.</p> <p>For example, if the Liquid file is located at <code>theme-app-extension/blocks/app-block.liquid</code>, then the <code>{handle}</code> is <code>app-block</code>.</p> <p>To see this Liquid file in the context of an app block, refer to the theme app extension <a href="https://github.com/Shopify/theme-extension-getting-started">getting started sample code</code></a>.</p> </td> <tr> <td><code>{header|footer|aside}</code></td> <td><p>The section group to which the app block should be added. Only "header," "footer," and "aside" are supported.</p></td> </tr> <tr> <td><code>{sectionID}</code></td> <td><p>The ID of the section to which the app block should be added. The <code>sectionID</code> must be prefixed by the string <code>sectionId</code>:</p> <p>Go to JSON templates: <a href="/docs/storefronts/themes/architecture/templates/json-templates#section-data">Section data</a> for an example of where a section ID can be found in a JSON template file.</p> </td> </tr> </table> #### Example URLs Your app needs to redirect merchants to a URL with populated parameters. **Adding an app block to any JSON template** The following is the deep link structure for adding an app block to any JSON template in a new Apps section: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="App block URL"></script> <script type="text/plain" data-language="text"> https://<myshopifyDomain>/admin/themes/current/editor?template=${template}&addAppBlockId={uuid}/{handle}&target=newAppsSection </script> </div> </p> For example, the deep link to add the `customer_review.liquid` block to the `Default product` template might look like the following: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="Adding customer_review block to the Default product template"></script> <script data-option="nocopy" data-value="true"></script> <script type="text/plain" data-language="text"> https://<myshopifyDomain>/admin/themes/current/editor?template=product& addAppBlockId=8f1f0756-d5fc-4c36-b7f4-b2aa8828ced8/customer_review&target=newAppsSection </script> </div> </p> > Tip: > Your app can target any JSON template in a theme that's published in the Shopify Theme Store. This is because all JSON templates are required to support app blocks in the [Apps section](/docs/storefronts/themes/architecture/blocks/app-blocks#app-block-wrapper). **Adding an app block to a section group** The following example shows a deep link structure for adding an app block to the header, footer, or aside section group: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="App block URL"></script> <script type="text/plain" data-language="text"> https://<myshopifyDomain>/admin/themes/current/editor?template={template}&addAppBlockId={uuid}/{handle}&target=sectionGroup:{header|footer|aside} </script> </div> </p> For example, the deep link to add the `announcement_bar.liquid` block to the `Header` section group might look like the following: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="Adding announcement_bar block to the Header section group"></script> <script data-option="nocopy" data-value="true"></script> <script type="text/plain" data-language="text"> https://<myshopifyDomain>/admin/themes/current/editor?template=product& addAppBlockId=8f1f0756-d5fc-4c36-b7f4-b2aa8828ced8/announcement_bar& target=sectionGroup:header </script> </div> </p> > Tip > You can verify the availability of a [section group](/docs/storefronts/themes/architecture/section-groups), such as header, footer, or aside, in a theme using the [`read_themes` access scope](/docs/api/usage/access-scopes#authenticated-access-scopes). This allows you to check if a specific section group is used in a theme before providing a merchant with a deep link to it. **Adding an app block to the main section** The main section is a section with `ID="main"`. The following example shows a deep link structure for adding an app block to the main section of a template: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="App block URL"></script> <script type="text/plain" data-language="text"> https://<myshopifyDomain>/admin/themes/current/editor?template={template}& addAppBlockId={uuid}/{handle}&target=mainSection </script> </div> </p> For example, the deep link to add the `star_rating.liquid` block to the main section of the `product.json` template might look like the following: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="Adding star_rating block to the main section of the product template"></script> <script data-option="nocopy" data-value="true"></script> <script type="text/plain" data-language="text"> https://<myshopifyDomain>/admin/themes/current/editor?template=product& addAppBlockId=8f1f0756-d5fc-4c36-b7f4-b2aa8828ced8/star_rating&target=mainSection </script> </div> </p> The following example of a theme's `product.json` template includes a section with an `id` of `main`. <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="templates/product.json"></script> <script data-option="nocopy" data-value="true"></script> <script type="text/plain" data-language="text"> { "sections": { "main": { "type": "product", "settings": { "show_vendor": true } }, }, "order": [ "main", ] } </script> </div> </p> > Tip: > Only the main section of the default product template is required to support app blocks. However, we recommend that all sections that have blocks should support app blocks. You can verify compatibility with the [`read_themes` access scope](/docs/api/usage/access-scopes#authenticated-access-scopes). **Adding an app block to a section using its ID** The following example shows a deep link structure for adding an app block to a section by targeting its ID: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="App block URL"></script> <script type="text/plain" data-language="text"> https://<myshopifyDomain>/admin/themes/current/editor?template={template}&addAppBlockId={uuid}/{handle}&target=sectionId:{sectionId} </script> </div> </p> For example, the deep link to add the `form.liquid` block to the `Newsletter` section of the `index.json` template might look like the following: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="Adding form block to the Newsletter section of the index.json template"></script> <script data-option="nocopy" data-value="true"></script> <script type="text/plain" data-language="text"> https://<myshopifyDomain>/admin/themes/current/editor?template=index& addAppBlockId=8f1f0756-d5fc-4c36-b7f4-b2aa8828ced8/form& target=sectionId:5ac3e115-be8f-4426-a09c-4397a1672899 </script> </div> </p> You can find the parameters for the section you want to target in the template's JSON file. For example, the parameters of the `Newsletter` of the index.json template are shown below: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="templates/index.json"></script> <script data-option="nocopy" data-value="true"></script> <script type="text/plain" data-language="text"> { "sections": { "5ac3e115-be8f-4426-a09c-4397a1672899": { "type": "newsletter" } }, "order": [ "5ac3e115-be8f-4426-a09c-4397a1672899" ] } </script> </div> </p> > Tip: > You can verify the availability of a section ID in a theme using [`read_themes` access scope](/docs/api/usage/access-scopes#authenticated-access-scopes). This allows you to check if a specific section (for example, `Newsletter` or `Featured product`) is used within a theme before providing a merchant with a deep link to it. #### App block errors and edge cases In the following scenarios, an error message is shown to merchants to guide them with next steps. When possible, you should take steps to prevent these errors. <table> <caption>App block errors and edge cases</caption> <tr> <th scope="col">Error scenario</th> <th scope="col">How to prevent</th> </tr> <tr> <td><p>Section limit has been reached in template or section group</p></td> <td><p>This error can't be prevented. The merchant will be invited to remove a section and try again.</p> </td> </tr> <tr> <td><p>Template is not found</p></td> <td><p>You can prevent this error by having your app verify the availability of a template, section group, or section with the <a href="/docs/api/usage/access-scopes#authenticated-access-scopes"><code>read_themes</code> access scope</a>.</p> </td> </tr> <tr> <td><p>Section is not found</p></td> <td> <p>If the error occurs, the app block will fall back to be added to the template instead.</p> <p>You can prevent this error by having your app verify the availability of a template, section group, or section with the <a href="/docs/api/usage/access-scopes#authenticated-access-scopes"><code>read_themes</code> access scope</a>.</p> </td> </tr> <tr> <td><p>Section group is not found</p></td> <td><p>You can prevent this error by having your app verify the availability of a template, section group, or section with the <a href="/docs/api/usage/access-scopes#authenticated-access-scopes"><code>read_themes</code> access scope</a>.</p> </td> </tr> <tr> <td><p>Template type is not supported in app block schema</p></td> <td><p>You can prevent this error by making sure that your app only deep links to templates that are supported in your app block's schema.</p> </td> </tr> </tr> <tr> <td><p>Typo in deep link URL </p></td> <td><p>You can prevent this error by testing deep links to confirm they work and don't contain typos.</p> </td> </tr> </tr> <tr> <td><p>Template doesn't have a resource to be rendered</p></td> <td><p>This error can't be prevented. The merchant will be invited to create a resource, such as a product, collection, or blog post, and then try again.</p> </td> </tr> </tr> <tr> <td><p>Template is liquid</p></td> <td><p>You can prevent this error by having your app verify compatibility of a template with the <a href="/docs/api/usage/access-scopes#authenticated-access-scopes"><code>read_themes</code> access scope</a>.</p> </td> </tr> </tr> <tr> <td><p>Section doesn't support blocks or app blocks</p></td> <td> <p>If the error occurs, the app block will fall back to be added to the template instead.</p> <p>You can prevent this error by having your app verify compatibility of a section with the <a href="/docs/api/usage/access-scopes#authenticated-access-scopes"><code>read_themes</code> access scope</a>.</p> </td> </tr> </tr> <tr> <td><p>Block limit has been reached in a section</p></td> <td><p>This error can't be prevented. The merchant will be invited to remove a block and try again.</p> </td> </tr> </table> #### App embed block deep linking You can implement a deep link to activate an app embed block directly in a theme. #### App embed block deep link URL query parameters <table> <caption>Deep link URL query parameters</caption> <tr> <th scope="col">Query parameter</th> <th scope="col">Description</th> </tr> <tr> <td><code>context</code></td> <td><p>The context in which the app is being activated. The value is <code>apps</code>.</p> <!--<p>If you're linking to an app embed block, then set <code>apps<code>.If you're linking to an app block, then don't set a value.</p>--> </td> </tr> <tr> <td><code>{template}</code></td> <td><p>The <!-- templates to which a block is added, or the -->templates on which a block is rendered. If not set, then Shopify will default to the <a href="/docs/storefronts/themes/architecture/templates/index-template">index template</a>.</p> <p>The possible values are <code>product</code>, <code>collection</code>, <code>article</code>, and <code>blog</code>.</a></p> </td> </tr> <tr> <td><code>{uuid}</code></td> <td><p>The ID of the theme app extension.</p> <p>Retrieve the <code>SHOPIFY_<EXTENSION_NAME>_ID</code> value from your project's <code>.env</code> file. This file is only available after you run the <code>deploy</code> command for the first time.</p> </td> <tr> <td><code>{handle}</code></td> <td><p>The filename of the block's Liquid file.</p> <p>For example, if the Liquid file is located at <code>theme-app-extension/blocks/app-embed.liquid</code>, then the <code>{handle}</code> is <code>app-embed</code>.</p> <p>To see this Liquid file in the context of an app embed block, refer to the theme app extension <a href="https://github.com/Shopify/theme-extension-getting-started">getting started sample code</code></a>.</p> </td> </table> #### App embed block deep linking URL Your app needs to redirect merchants to the following URL, with URL query parameters populated: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="App embed block URL"></script> <script type="text/plain" data-language="url"> https://<myshopifyDomain>/admin/themes/current/editor?context=apps&template=${template}&activateAppId={uuid}/{handle} </script> </div> </p> You can retrieve the `<myshopifyDomain>` value from the [`Shop` GraphQL Admin API object](/docs/api/admin-graphql/latest/objects/shop). ### Performance All files inside the `assets/` folder are automatically served from [Shopify's CDN](/docs/storefronts/themes/best-practices/performance#host-assets-on-shopify-servers) for fast, reliable asset delivery. Reference your assets by using either the `javascript` and `stylesheet` [schema](#schema) attributes or using the [`asset_url`](/docs/api/liquid/filters/asset_url) and [`asset_img_url`](/docs/api/liquid/filters/asset_img_url) Liquid URL filters. For app embed blocks, take advantage of their ability to only load scripts on specific pages. ### Theme editor compatibility You need to ensure that the app works in the [theme editor](/docs/storefronts/themes/tools/online-editor) environment. If necessary, you can set your app to [detect the theme editor](/docs/storefronts/themes/architecture/sections/integrate-sections-with-the-theme-editor#detect-the-theme-editor), so that you can adjust your app to work in that environment. ### Detecting app blocks and app embed blocks If you want to identify whether a merchant has added app blocks to their theme, or enabled app embed blocks, you can use the [`Asset` REST Admin API resource](/docs/apps/build/online-store/asset-legacy) to look for blocks that match your app type. #### Detecting app blocks When a merchant adds an app block to a theme, a reference to the app block is added to the template JSON file. You can identify your app block by the block type, which uses the following syntax: ```json "<block_unique_ID>": { "type:": "<partner_name>:\/\/apps\/<app_name>\/blocks\/<block_name>\/<unique_ID>" ``` An app block is given a unique ID, and the `type` value is appended with a unique ID which identifies the app. The following example contains two app blocks from the same app: one in the `main-product` section, and one in an `apps` section. <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="templates/product.json"></script> <script type="text/plain" data-language="json"> { "sections": { "main": { "type": "main-product", "blocks": { "title": { "type": "title", "settings": { } }, "dc0a5152-193b-4663-9203-6153357d0c8e": { "type": "shopify:\/\/apps\/product-reviews\/blocks\/star_rating\/bae150af-8da8-48b2-9867-398188115e5f", "settings": { "stars_fill_color": "#44ff00", "star_size": 15, "text_align": "flex-start", "product": "", "stars_text_empty": "No reviews" } }, ... }, "block_order": [ "title", "dc0a5152-193b-4663-9203-6153357d0c8e" ... ], "settings": { ... } }, "164193020622fc8e2f": { "type": "apps", "blocks": { "cadef24e-ecf6-49f8-a544-6bb5186af219": { "type": "shopify:\/\/apps\/product-reviews\/blocks\/reviews\/bae150af-8da8-48b2-9867-398188115e5f", "settings": { } } }, "block_order": [ "cadef24e-ecf6-49f8-a544-6bb5186af219" ], "settings": { ... } } }, ... } </script> </div> </p> #### Detecting app embed blocks App embed blocks appear in `settings_data.json`. An app embed block is added to `settings_data.json` only after it's enabled for the first time. If the app embed block is disabled after it's been enabled, then it remains in `settings_data.json`, and `disabled` is set to `true`. You can identify your app block by the block type, which uses the following syntax: ```json "<block_unique_ID>": { "type:": "<partner_name>:\/\/apps\/<app_name>\/blocks\/<block_name>\/<unique_ID>" ``` An app block is given a unique ID, and the `type` value is appended with a unique ID which identifies the app. <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="config/settings_data.json"></script> <script type="text/plain" data-language="json"> { "current": { "sections": { ... }, "content_for_index": [ ], "blocks": { "17878678986028907411": { "type": "shopify:\/\/apps\/faceforms-better-pop-ups\/blocks\/app-embed\/f2173231-e611-461d-884b-bd8e6cc2ded4", "disabled": false, "settings": { ... } } } } } </script> </div> </p> ### Reserved prefixes for metafields and metaobjects You can reference reserved namespaces and reserved types for metafields and metaobjects using [reserved prefixes](/docs/apps/build/custom-data/ownership#reserved-prefixes) in your theme app extension Liquid snippets. This approach eliminates the need to hardcode app IDs and simplifies developing your app for different environments, such as testing and production. #### Metafield namespaces The following example assumes a metafield value for the key `my_key` has been set under a metafield within a reserved namespace `$app:custom`. The value can be referenced using the following syntax: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="/blocks/metafield.liquid"></script> <script type="text/plain" data-language="liquid"> block.settings.product.metafields["$app:custom"].my_key.value </script> </div> </p> #### Metaobject types The following example assumes a metaobject definition has been created with a reserved type `$app:custom`, and a metaobject has been created with a handle of `my_handle` and a field for the key `my_key`. The value can be referenced using the following syntax: <p> <div class="react-code-block" data-preset="file"> <div class="react-code-block-preload ThemeMode-dim"> <div class="react-code-block-preload-bar "></div> <div class="react-code-block-preload-placeholder-container"> <div class="react-code-block-preload-code-container"> <div class="react-code-block-preload-codeline-number"></div> <div class="react-code-block-preload-codeline"></div> </div> </div> </div> <script data-option="filename" data-value="/blocks/metaobject.liquid"></script> <script type="text/plain" data-language="liquid"> shop.metaobjects["$app:custom"]["my_handle"].my_key.value </script> </div> </p> ## File and content size limits Shopify validates theme app extensions when you [deploy your extension](/docs/apps/build/online-store/theme-app-extensions/build#step-5-deploy-and-release-the-extension). If the app's content exceeds any file and content size limits, then the theme app extension fails validation and doesn't update. The following table provides the enforced, and suggested, limits on theme app extensions: <table> <caption>Limits</caption> <tr> <th scope="col">App content</th> <th scope="col">Limit</th> <th scope="col">Enforced or suggested</th> </tr> <tr> <td>All files in a theme app extension</td> <td>10 MB</td> <td>Enforced</td> </tr> <tr> <td>Number of blocks</td> <td>25</td> <td>Enforced</td> </tr> <tr> <td>Number of locale files in the extension</td> <td>100</td> <td>Enforced</td> </tr> <tr> <td>Size of each locale file</td> <td>15 KB</td> <td>Enforced</td> </tr> <tr> <td>Size of Liquid across all files</td> <td>100 KB</td> <td>Enforced</td> </tr> <tr> <td>Size of CSS (compressed) referenced directly by the schema</td> <td>100 KB</td> <td>Suggested</td> </tr> <tr> <td>Size of JS (compressed) referenced directly by the schema</td> <td>10 KB</td> <td>Suggested</td> </tr> </table> ## Restrictions The following pages and objects can't be used with theme app extensions. ### Pages Theme app extension app blocks and app embed blocks can't be rendered on [checkout pages](/docs/storefronts/themes/architecture/layouts/checkout-liquid#checkout-steps). This includes all pages that are rendered when a customer initiates a checkout, such as **Contact information**, **Shipping method**, **Payment method**, and **Order status**. ### Liquid objects Theme app extensions don't have access to the following Liquid objects or properties: - The [`content_for_header`](/docs/api/liquid/objects/content_for_header) object - The [`content_for_index`](/docs/api/liquid/objects/content_for_index) object - The [`content_for_layout`](/docs/api/liquid/objects/content_for_layout) object - Any properties of the parent [`section`](/docs/api/liquid/objects/content_for_layout) object, other than `id`. You can use the `id` property to interact with the [section rendering API](/docs/api/ajax/section-rendering). #### Section Liquid Object App blocks have access to their parent [section](/docs/api/liquid/objects/section) liquid object. Only the ID property is accessible, which can be used with the [section rendering API](/docs/api/ajax/section-rendering). ### JSON with comments Theme app extensions do not support comments and trailing commas in JSON like [theme files](/docs/storefronts/themes/architecture#json-with-comments). ## Next steps * [Get started](/docs/apps/build/online-store/theme-app-extensions/build) building a theme app extension.