shopify
Shopify theme app extensions, explained for merchants and developers
What Shopify theme app extensions actually are, how app embeds and app blocks work, and why they replaced script tags for every Online Store 2.0 theme.

If you've installed a Shopify app in the last three years and noticed that it just worked — no copy-pasting a script tag into theme.liquid, no support ticket asking a developer to add an include — you have theme app extensions to thank. They're the boring infrastructure piece that quietly fixed most of what merchants used to hate about installing Shopify apps. This is a plain-English guide to what they are, the three surfaces they use, what they replaced, and why every serious app in 2026 ships one.
TL;DR
- Theme app extensions (TAEs) are bundles of Liquid, CSS, and JS that an app ships into your theme without modifying theme files.
- They come in three flavors: app embeds (global, like a tracking pixel), app blocks (slot into a section, like a reviews widget), and app sections (a whole new section type).
- They replaced the old ScriptTag API and Asset API patterns that Shopify deprecated for Online Store 2.0 themes.
- Merchants enable them with a toggle in the theme editor — no code, no copy-paste, and they survive theme updates.
- Developers ship them through the Shopify CLI, versioned per app deploy. Pulsar is a working example of an app embed.

What a theme app extension actually is
A theme app extension is a directory inside your app's repo that contains Liquid templates, CSS, and JS. When the app is installed, Shopify makes those files available to the merchant's theme as if they were native theme assets — but they live on Shopify's CDN, not in the theme's file tree. The merchant never sees them in Edit code. They appear instead as togglable blocks in the Customize view of the theme editor.
Concretely: in the app's source, a TAE looks like this:
extensions/
pulsar-inline/
blocks/
pulsar.liquid # the actual storefront code
shopify.extension.toml # metadata: type, name, target surfaces
assets/ # optional CSS/JS shipped alongsideWhen the developer runs shopify app deploy, Shopify uploads that directory and pins it to the current app version. The merchant's theme editor then exposes the block by name — in Pulsar's case, Pulsar Inline — and they enable it with a click.
Why Shopify introduced them (the 2022 reset)
Before Online Store 2.0 launched in mid-2021 and TAEs became the recommended pattern in 2022, apps that needed to run code on the storefront had two ugly options. Neither was good.
Option 1: the ScriptTag API
The app called the ScriptTag Admin API endpoint to inject a <script src="..."></script> tag into every page on the storefront. This worked, but it had real problems: every app added a render-blocking script, the merchant had no visibility into what was loading, the script lived on the app's servers (so an app outage = a broken storefront), and there was no UI for the merchant to turn it off short of uninstalling.
Option 2: editing theme.liquid directly
Apps would programmatically modify the theme's Liquid files via the Asset API — appending an include line to theme.liquid or to a section template. This was even worse: a theme update wiped the change, a different app's edit could clobber yours, and the merchant ended up with a theme.liquid full of mystery includes no one could explain.
The three surfaces
TAEs come in three shapes, picked based on where the app code needs to run. Every TAE you'll meet is one of these three.
1. App embeds
Global. Loaded on every page of the storefront. Used for things that aren't tied to one section — tracking pixels, chat widgets, A/B test scripts, theme-wide scanners. The merchant enables them from the theme editor's App embeds panel in the left sidebar.
Pulsar's pulsar-inline is an app embed: it scans every h1, h2, and p on the page for Pulsar syntax and rewrites the matches into styled spans. It needs to be global because the merchant might use Pulsar syntax in any section, so the scanner has to run everywhere.
2. App blocks
Slot into an existing section. The merchant opens a section (product info, image banner, custom liquid section, etc.), clicks Add block, and your app's block appears in the picker alongside the theme's native blocks. Used for product reviews widgets, size charts, trust badges, country selectors — anything that belongs inside a specific section.
3. App sections
A whole new section type. The merchant adds it like any other section. Used for full-width app-owned UI: subscription pickers that take over the product page, lookbook galleries, multi-step quizzes. Less common than embeds and blocks because most apps don't need that much real estate, but the cleanest option when they do.

TAE vs ScriptTag vs theme code edit
If you're still seeing apps in 2026 that ask you to paste code into your theme.liquid, this is what you're being asked to give up.
| Capability | Theme app extension | ScriptTag API | Manual theme code edit |
|---|---|---|---|
| Install effort for merchant | One toggle | Automatic but invisible | Copy-paste into theme.liquid |
| Survives theme updates | Yes | Yes | No — wiped on update |
| Survives theme swaps | Yes (re-enable in new theme) | Yes | No — every swap requires re-paste |
| Editable from theme editor | Yes | No | No |
| Render-blocking risk | Async by default | Often render-blocking | Whatever you pasted |
| Sandboxed from theme code | Yes | No (touches the DOM globally) | No |
| Versioned per app release | Yes | No (live URL) | No |
| Uninstall is clean | Yes | Sometimes leaves orphans | No — code stays after uninstall |
| Status in 2026 | Current standard | Deprecated for OS 2.0 | Avoid |
What this looks like as a merchant
From the merchant side, the difference between installing a 2026 app and a 2019 app is night and day. Here's the modern flow:
- Install the app from the Shopify App Store. OAuth, redirected back to the admin.
- The app's onboarding tells you to open the theme editor and enable its embed or block.
- You open Online Store → Themes → Customize.
- In the left sidebar, click the App embeds icon (a puzzle piece). The app's embed is in the list with a toggle.
- Toggle it on. Hit Save. Reload your storefront. The app is live.
No code editor opened. No theme.liquid modified. If you swap themes, you re-enable the embed in the new theme and you're done — the app's code didn't live in the old theme, so swapping doesn't break it.
For a step-by-step walkthrough with screenshots, see how to install Pulsar step by step — the flow is identical for any modern app embed.
What this looks like as a developer
From the developer side, TAEs are a Shopify CLI workflow. You scaffold an extension, edit Liquid, and ship it with the rest of your app.
Scaffold
shopify app generate extension
# pick "Theme app extension"
# give it a handle, e.g. pulsar-inlineThis creates an extensions/<handle>/ directory with a shopify.extension.toml, a blocks/ folder, and an assets/ folder. You write Liquid in blocks/. Each .liquid file in there becomes one app block or app embed, controlled by a {% schema %} tag at the bottom of the file.
Example: a minimal app embed schema
<script>
console.log("My app embed is live on", window.location.pathname);
</script>
{% schema %}
{
"name": "My App Embed",
"target": "head",
"settings": [
{
"type": "checkbox",
"id": "enabled",
"label": "Enable my app",
"default": true
}
]
}
{% endschema %}The target field is the part that makes this an embed: setting it to head, body, or section controls where it gets injected globally. Omit target and add a templates array instead and you get an app block that can be slotted into sections by the merchant.
Deploy
shopify app deployThis pushes the extension up alongside your app config (scopes, webhooks, app proxy). Each deploy creates a new app version; merchants get the new TAE code the next time they reload the storefront, no theme republish required.

A real-world example: Pulsar Inline
Pulsar is the text-effects app this blog belongs to, and pulsar-inline is a textbook app embed. Here's the entire architecture in three sentences:
- One Liquid file —
extensions/pulsar-inline/blocks/pulsar.liquid— registers a global script that runs on every storefront page. - The script scans the DOM (default selectors:
h1, h2, p) for a tiny custom syntax (@{red-blue}word@,$c{...}text$, etc.). - Matches get rewritten in-place into styled spans or custom elements (
<pulsar-circle>,<pulsar-highlight>) that handle the SVG animations.
There is no theme code change. The merchant types Pulsar syntax into any rich text or heading field — product titles, section headlines, image banners — and it renders styled on the storefront. If they uninstall Pulsar, the embed goes away cleanly and their raw syntax just shows as plain text. No orphan scripts, no theme.liquid edits to undo. That's the whole pitch of TAEs in one example.
For a deeper look at the no-code editing flow this enables, see Shopify theme customization without code.
The Online Store 2.0 connection
Theme app extensions and Online Store 2.0 are not the same thing, but they're inseparable in practice. OS 2.0 (launched June 2021) was the architectural shift that made every theme template into a JSON file composed of sections and blocks. TAEs (made GA in early 2022) were the matching shift for apps — letting them participate in that section-and-blocks model as first-class citizens instead of bolt-on scripts.
If your theme is Dawn, Sense, Refresh, Crave, Studio, or any of Shopify's free themes from 2021 onward, you're on OS 2.0 and TAEs work everywhere. If you're on a paid theme from a third-party developer released in the last three years, same. If you're on a custom theme from 2018 that was never migrated, app embeds won't appear in your theme editor at all — that's the canary for needing a theme upgrade.
What TAEs don't fix
Worth being honest about the limits.
- Performance is still on you as a dev. TAEs don't magically defer your script. If you ship a 200KB blocking JS file in your embed, the storefront pays for it.
- Merchants still have to know to toggle the embed on. Plenty of apps install but stay invisible because the merchant never opened the theme editor. Good onboarding inside the admin UI is still required.
- You can't reach across embeds. Each TAE is conceptually isolated. If two apps both want to wrap the same H1, the last-loaded one wins.
- Schema constraints. Settings exposed to the theme editor have a fixed list of input types. Complex configuration still belongs in the embedded admin UI, not the theme editor.
FAQ
+How do I tell if an app is using a theme app extension or a script tag?
theme.liquid for stray includes.+Will a theme app extension survive when I switch themes?
+Why don't I see App embeds in my theme editor sidebar?
+Can a TAE slow down my storefront?
defer/async loading, and merchants can disable any embed instantly from the theme editor without uninstalling the app.+Do I need to be on a paid Shopify plan to use theme app extensions?
Bottom line
Theme app extensions are the boring, correct way for apps to live inside your Shopify storefront. They replaced a decade of duct-tape patterns — injected script tags, programmatic theme edits, copy-pasted snippets — with a single toggle in the theme editor and a clean uninstall. If you're a merchant, look for App embeds support before installing anything new. If you're a developer, every new app you ship in 2026 should be TAE-first.
Pulsar is one example you can install in under two minutes to see the whole pattern end-to-end — install the app, toggle one embed, type some syntax into a headline, and watch a global script rewrite your storefront text without touching a single theme file.
About the author
The Pulsar team
Shopify text styling
Pulsar is the easiest way to stylize headlines in your Shopify store — colors, gradients, animated highlights and circles, no theme code required.
Install Pulsar — Free


