If you’ve spent any time in Shopify’s developer documentation, you’ve probably noticed that “app blocks” and “theme app extensions” get used almost interchangeably in casual conversation, even though they’re not the same thing. One is a feature. The other is the mechanism that delivers it. Mixing them up is a common source of confusion for developers building their first Online Store 2.0 app, and it leads to some genuinely bad architecture decisions if you don’t sort it out early.
This post untangles the two, explains how they fit together, and covers the practical gotchas that only show up once you’re actually building, not when you’re reading the quick-start guide.
We work on custom Shopify builds regularly, including apps and theme integrations for Australian merchants, so this is written from the position of someone who has actually had to debug why a block wouldn’t render in a merchant’s theme at 4pm on a Friday.
The short answer
A theme app extension is the packaging mechanism: a set of files (blocks, snippets, assets, locales) that your app registers with Shopify and that a merchant can then add to their theme through the theme editor, without you touching their theme code directly.
An app block is one of the things a theme app extension can contain, a modular, drag-and-drop component (like a product recommendation carousel, a trust badge row, or a custom size guide) that a merchant places into a section using the theme editor’s native block system.
So the relationship isn’t “versus” in the sense of competing options, it’s more that app blocks are one deliverable inside the theme app extension framework, alongside app embed blocks, blocks for the theme editor’s app sections, and (for checkout) UI extensions on a separate but related system. You don’t choose one over the other; you build a theme app extension, and within it you decide whether you need blocks, embeds, or both.
Why this distinction actually matters
Before Online Store 2.0 (and its underlying JSON template architecture), most apps that needed to inject storefront functionality did one of two things: they asked merchants to manually paste Liquid snippets into theme.liquid or a specific template file, or they injected functionality via ScriptTag, a script that gets loaded on every storefront page regardless of whether it’s needed there.
Both approaches have real downsides that show up in production:
- Manual snippet edits break silently when a merchant updates their theme, because the merchant (or their next developer) doesn’t know your code is in there, and it gets wiped out on the next theme update.
- ScriptTags load on every page, which drags on page speed even on pages where your app does nothing, a real problem when Core Web Vitals affect both user experience and, increasingly, how Google evaluates page quality.
Theme app extensions solve this by letting Shopify host and version your app’s front-end code separately from the merchant’s theme code, while still rendering natively inside it. The merchant adds your block through the theme editor, drags it where they want it, and if they switch themes or update their theme, your extension isn’t silently deleted along with a hardcoded Liquid include.
How theme app extensions are structured
A theme app extension lives in your app’s codebase (built with Shopify CLI) and typically contains:
blocks/, Liquid files defining app blocks that merchants add inside sectionssnippets/, reusable Liquid partials referenced by your blocksassets/, CSS, JS, images scoped to your extensionlocales/, translation files for the block’s merchant-facing settingsshopify.extension.toml, configuration defining the extension’s type and settings schema
When you run shopify app generate extension and choose “Theme app extension,” the CLI scaffolds this structure for you. You then define the block’s settings schema (text fields, colour pickers, product pickers, and so on) almost exactly the way you’d define settings for a native theme section, which is deliberate, because it means merchants get a familiar editing experience without you writing custom admin UI.
App blocks vs app embed blocks: the distinction developers actually get wrong
Within a theme app extension, there are two practical categories worth separating clearly, because they behave differently:
App blocks are placed inside a section by the merchant, the same way they’d add a native “Image with text” block. They only render where the merchant explicitly drags them, inside sections that support app blocks (which, for Online Store 2.0 themes, is most JSON-template sections, but not every legacy or custom section unless the theme developer has explicitly enabled "blocks" support in the section schema).
App embed blocks are toggled on/off globally in the theme editor’s “App embeds” panel, and they render at a fixed point in the theme (commonly just before </body>), not inside a specific section. These are the right tool for things that need to run everywhere, a chat widget, an analytics pixel, a cart drawer enhancement, rather than something a merchant places deliberately on one page.
Getting this choice backwards causes two common support headaches:
- Building something as an app block when it should be an embed, the merchant has to manually add it to every template it needs to appear on, and forgets one, and then wonders why the feature “randomly doesn’t work” on the collection page.
- Building something as an embed when it should be a block, the merchant loses control over where on the page it appears, and ends up asking for a level of positioning control the embed format was never designed to give them.
A practical checklist before you start building
If you’re scoping a Shopify app that needs to touch the storefront, run through this before writing code:
- Does the merchant need to control exactly where it appears on the page? → App block.
- Does it need to run on every page regardless of layout? → App embed block.
- Does the target section actually support app blocks? Check the section’s schema for
"blocks"with a"type": "@app"entry, if the theme developer hasn’t added this, merchants can’t place your block there no matter how correctly you’ve built it. This is the single most common “why isn’t my block showing up” support ticket, and it’s a theme-side limitation, not an extension bug. - Does the merchant need to configure text, colours, or product references? Build that into the block’s settings schema rather than hardcoding it, so non-technical store owners can adjust it themselves.
- Will this need to work inside checkout, not just the storefront? Theme app extensions don’t cover checkout, that’s a separate extension type (checkout UI extensions) with its own APIs and constraints, and it’s a meaningfully different build.
Where this gets genuinely tricky
A few things trip up even experienced developers:
Older themes may not support app blocks at all. If a merchant is on a vintage (pre-2.0) theme, or a heavily customised theme where the developer hasn’t added app block support to relevant sections, your extension has nowhere to render. This is worth checking before you promise a feature will “just work”, it depends on the merchant’s specific theme, not just their Shopify plan.
Settings changes require merchant action. Unlike a native app feature you control entirely server-side, changes to a block’s placement or visibility always require the merchant to go into the theme editor and adjust it. You can ship a new block version, but you can’t force it onto a page the merchant hasn’t added it to.
Testing across themes matters more than it does for admin-only apps. A block that renders perfectly in Dawn (Shopify’s reference theme) can break in a heavily customised third-party theme with unusual CSS resets or JS conflicts. If your app is aimed at a broad merchant base, budget real QA time across a handful of popular theme families, not just the default.
When to bring in a specialist
Theme app extensions sit at the intersection of app development and theme architecture, which is exactly the kind of build where a developer who only knows one side tends to produce something that technically works but causes friction for merchants, blocks that don’t respect theme styling, embeds that fire on pages they shouldn’t, or settings schemas that don’t match how a store owner actually thinks about the feature. If you’re building or commissioning an app that needs to inject storefront functionality cleanly, this is a good candidate for a proper scoping conversation with a Shopify app development team before the CLI scaffold gets written, not after.
FAQ
Can I use app blocks on the cart or checkout page?
Not directly. App blocks work within Online Store 2.0 sections on storefront pages. Checkout customisation uses a separate extension type, checkout UI extensions, built with a different API and, on some Shopify plans, different availability. Treat them as two separate builds even if they’re for the same overall feature.
Do theme app extensions work with legacy (non-Online Store 2.0) themes?
No. Theme app extensions rely on the JSON template and section architecture introduced with Online Store 2.0. If a merchant is on an older theme, they’d need to update or migrate their theme before your extension can render at all.
Why isn’t my app block showing up in the theme editor?
The most common cause is that the target section’s schema doesn’t include a "blocks" array with an "@app" type entry, meaning the theme itself hasn’t opted in to accepting app blocks in that section. Check the section file directly rather than assuming it’s an extension-side bug.
Can a merchant break my app block by removing it accidentally?
Yes, because it lives in the merchant’s own section/block layout, it’s just as removable as any native block. This is a trade-off of the flexibility theme app extensions offer; some apps mitigate it by also shipping an app embed as a fallback for critical functionality.
Is there a limit to how many app blocks one extension can register?
Shopify’s platform limits change over time, so rather than quoting a specific number that may be out of date, the practical approach is to design your extension around a small number of well-scoped blocks rather than a large sprawling set, it’s easier for merchants to understand and for you to maintain.
Ready to build this properly?
If you’re scoping an app that needs to extend a Shopify storefront and want it built to actually survive theme updates and merchant customisation, book a call with our team and we’ll talk through the right extension architecture for what you’re trying to do.