The short version
- An app block sits inline at a specific spot in a theme section, and merchants can add, move and remove it in the theme editor. Use it for content tied to a place on the page, such as reviews, star ratings or a badge next to the price.
- An app embed block is injected before the closing
</head>or</body>tag. Use it for floating or overlaid UI, such as a chat bubble, and for scripts with no UI of their own. - Blocks are off by default after install. Merchants have to add an app block or switch on an app embed block, so onboarding matters as much as the code.
- Neither can render on checkout pages. Use checkout UI extensions there.
Last verified against Shopify's developer documentation on October 19, 2026.
If you build Shopify apps, or you buy custom ones, this choice shapes more than the code. It decides who controls placement, whether the app works on older themes, how merchants install it, and how much it costs the storefront in speed.
Script tags used to hide that choice by injecting code anywhere. With script tags on the way out (see our Shopify script tag migration guide), every storefront feature has to choose a block type. This guide shows how to choose, how to ship each type, and how to get merchants to turn them on.
What is the difference between an app block and an app embed block?
Theme app extension: a bundle of app blocks, app embed blocks, assets and snippets that an app ships to extend a merchant's theme without editing theme code. App blocks and app embed blocks are its two storefront surfaces.
| App block | App embed block | |
|---|---|---|
Schema target
|
section |
head, body or compliance_head
|
| Where it renders | Inline, inside a theme section or as a section-level wrapped block | Injected before the closing </head> or </body> tag |
| How merchants add it | From the Apps section of the theme editor, onto a compatible section | Switched on in Theme Settings > App embeds |
| Theme support | Needs a theme with JSON templates and sections that support @app blocks |
Works in vintage and Online Store 2.0 themes |
| Dynamic data | Yes. autofill resource settings can point to the section's product, collection and so on |
No. It only has the global Liquid scope of the page |
| Merchant control | Merchants can reposition and reorder it | On or off, plus its settings |
| Typical use | Product reviews, star ratings, a full-width section | Chat bubbles, product image badges, SEO meta tags, analytics scripts |
The one-line rule: if the content belongs in a particular place on the page, it is an app block. If it floats over the page or has no UI, it is an app embed block.
When does your app need an app block?
Reach for an app block when any of these is true:
- The content points to dynamic data, such as a reviews widget that must follow whichever product the page shows.
- Merchants will want to move it around the page.
- It should span the full width of the page.
Here is a star rating block. The autofill setting is what makes it useful: Shopify fills the product setting automatically with the section's product, or the template's resource, when a merchant adds the block.
{%- assign product = block.settings.product -%}
<div class="star-rating" data-product-id="{{ product.id }}">
{{ block.settings.heading }}
</div>
{% schema %}
{
"name": "Star rating",
"target": "section",
"javascript": "star-rating.js",
"stylesheet": "star-rating.css",
"enabled_on": { "templates": ["product"] },
"settings": [
{ "type": "product", "id": "product", "label": "Product", "autofill": true },
{ "type": "text", "id": "heading", "label": "Heading", "default": "Rated by customers" }
]
}
{% endschema %}
The catch is theme support. For app blocks to work, the theme needs JSON templates and sections that support and render blocks of type @app. Shopify's Dawn main-product section is the reference implementation, and Shopify documents a way to verify whether a theme supports app blocks. Don't assume. Test on the themes your customers actually run.
When does your app need an app embed block?
Reach for an app embed block when the feature has no UI of its own, or when it floats or overlays the page:
- A chat bubble, a cookie banner, a badge over product images.
- A script that has to load site-wide, or on chosen templates.
- Anything that must work on vintage themes without a second install path.
<div class="chat-launcher" data-position="{{ block.settings.position }}"></div>
{% schema %}
{
"name": "Chat launcher",
"target": "body",
"javascript": "chat-launcher.js",
"stylesheet": "chat-launcher.css",
"enabled_on": { "templates": ["index", "collection", "product"] },
"settings": [
{
"type": "select",
"id": "position",
"label": "Position",
"default": "right",
"options": [
{ "value": "left", "label": "Left" },
{ "value": "right", "label": "Right" }
]
}
]
}
{% endschema %}
Three details that matter:
-
enabled_onlimits where it loads. App embed blocks can load scripts only on specific pages, which script tags could never do. That is a performance win you should always take. -
compliance_headloads first. Shopify says to use it only when necessary, for example for a cookie consent banner. - Embeds can't read dynamic sources. They only see the global Liquid scope for the page they render on. If you need the current product's resource as a setting, you need an app block.
One boundary to respect: if your embed only collects analytics events and draws nothing, a web pixel is the better tool. It respects consent and needs no merchant action. Our guide to the Shopify Web Pixels API covers what a pixel can and can't do.
Can an app use both block types?
Yes, and many good apps do. A single extension holds up to 30 blocks, each file with one target. A common pattern is an app embed block that loads shared scripts and global configuration, plus app blocks that render the UI at placement points.
If you declare the same JavaScript or CSS file in several blocks that appear on one page, Shopify includes the file only once. That makes a shared bundle cheap to reuse across blocks.
Don't try to make one block file do both jobs. A block has one target, so "section" and "body" are always separate files. A common developer mistake is changing a block's target from section to head or body because it didn't show up under App embeds, and then wondering why it vanished from the template picker. The fix is two files, not one.
How do merchants activate your blocks?
This is where installs quietly die. By default, themes don't include app blocks after an app is installed, and app embed blocks are deactivated until a merchant turns them on. If your onboarding says "go to the theme editor and find the block," a lot of merchants won't.
Use deep links. After install, send the merchant to the theme editor with your block already added or switched on, where they can preview it and save. The URL patterns look like this (replace the placeholders, where the handle is your block's Liquid filename and the API key is your app's client ID):
# Activate an app embed block
https://SHOP.myshopify.com/admin/themes/current/editor?context=apps&template=product&activateAppId={api_key}/{handle}
# Add an app block to a new Apps section on a template
https://SHOP.myshopify.com/admin/themes/current/editor?template=product&addAppBlockId={api_key}/{handle}&target=newAppsSection
# Add an app block to the main section, or a section group
...&addAppBlockId={api_key}/{handle}&target=mainSection
...&addAppBlockId={api_key}/{handle}&target=sectionGroup:header
Two limits to know: you can deep link only to sections that support app blocks, and only one app block at a time.
Then check whether it worked. From your app in the Shopify admin, shopify.app.extensions() returns the activation status of each of your blocks on the published theme, with no extra access scopes. Server-side, you can read theme files with the read_themes scope. App embeds appear in config/settings_data.json only after they are first enabled, and they stay there with disabled set to true if switched off later.
One trap from our script tag work applies here too. A block is only active on the theme it was enabled on. When a merchant publishes a new theme, your embed is off again, and the activation check tells you so.
What are the limits and restrictions for theme app extensions?
| Item | Limit | Type |
|---|---|---|
| All files in a theme app extension | 10 MB | Enforced |
| Number of blocks | 30 | Enforced |
| Size of Liquid across all files | 100 KB | Enforced |
| Locale files | 100 files, 15 KB each | Enforced |
| CSS referenced directly by the schema (compressed) | 100 KB | Suggested |
| JavaScript referenced directly by the schema (compressed) | 10 KB | Suggested |
Shopify validates these when you deploy, and an extension that breaks an enforced limit fails validation and doesn't update. The restrictions are as important as the limits:
- No checkout pages. App blocks and app embed blocks can't render on checkout pages. That covers contact information, shipping method, payment method and order status. Use checkout UI extensions for those, which is work our Shopify checkout extensions team does.
-
Limited Liquid objects. No access to
content_for_header,content_for_indexorcontent_for_layout, and only theidof the parentsection. - No JSON comments or trailing commas in extension JSON, unlike theme files.
How do you keep theme app extensions fast?
- Stay inside the suggested budgets. Keep JavaScript referenced by the schema to about 10 KB compressed and CSS to about 100 KB. Load anything heavier on demand.
-
Scope embeds with
enabled_on. Don't load a chat widget on pages where it isn't shown. -
Serve from the extension's
assetsfolder. Everything there is served from Shopify's CDN automatically. -
Reserve space for injected content. Shopify wraps every app block in an element with the
shopify-app-blockclass. A merchant can add custom CSS on the parent section that targets that class and sets amin-height, which prevents layout shift. App embed blocks are injected into<head>or<body>instead of a section, so that section-scoped CSS can't reach them. Design floating elements so they don't push content when they load. - Make the block work in the theme editor. Detect the editor and adjust, or merchants will see a broken preview.
If you ship a public app and want this reviewed, our bespoke app development team builds and audits theme app extensions, and our app and theme updates service keeps them current as themes change. If you are weighing who should own the work, our guide on how to choose a Shopify development agency lists the questions to ask.
Common questions about app embed blocks and app blocks
Do Shopify app embed blocks work on older themes?
Yes. App embed blocks work in both vintage themes and Online Store 2.0 themes, because they don't rely on sections or JSON templates. App blocks are different: they need a theme with JSON templates and sections that support blocks of type @app.
Are app embed blocks on by default after an app is installed?
No. App embed blocks are deactivated after install, and merchants activate them in the theme editor under Theme Settings > App embeds. App blocks also aren't added automatically. Your app can send merchants a deep link to the theme editor so the block is activated or added for them to preview and save.
Why isn't my app block showing in the theme editor?
The usual cause is theme support: the template may not be a JSON template, or the section may not support and render @app blocks. Check that the template appears in your block's enabled_on list, and that you set the target to section and not head or body. Shopify provides a way to verify whether a theme supports app blocks.
Can I use an app block or app embed block on the Shopify checkout page?
No. Neither block type can render on checkout pages, including the contact information, shipping method, payment method and order status steps. Use checkout UI extensions to add interface elements to checkout.
Should I use an app embed block or a web pixel for tracking?
Use a web pixel when the script only collects analytics or conversion data, because it respects customer consent and needs no merchant action. Use an app embed block when the code draws something on the page or has to run in the theme. Web pixels can't touch the DOM, so UI always needs a block.
Can an agency build a Shopify theme app extension for my app?
Yes. BrainBox Infoway provides Shopify development and AI automation for ecommerce from Ahmedabad, India, with ~20 specialists serving merchants and agencies in the US, EU, AUS, and CAN. The team builds theme app extensions, replaces legacy script tags with app blocks and app embed blocks, and tests them across the themes your merchants use. Agencies can hand the work over under a white-label arrangement, or you can get a free quote for your store.