Introduction

Shopify’s Theme App Extensions (TAEs) are a game-changer for developers looking to integrate custom app functionality directly into merchant themes without asking store owners to touch Liquid files.

Recently, we implemented a Theme App Extension to add a custom product badge and floating widget that could be toggled on/off from the Theme Editor. This case study walks you through the exact problem, approach, solution, and results so you can replicate it for your own projects.

1. Problem

Our Shopify app needed to display dynamic product badges on product pages and a global floating widget site-wide.

Challenges:

  • Merchants using Online Store 2.0 wanted zero code editing.
  • The solution had to load only when enabled to keep storefronts fast.
  • Both features required easy customization from the Theme Editor.

2. Approach

We chose to build a Theme App Extension with two elements:

  1. App Block → For product-specific badges.
  2. App Embed Block → For a global floating widget.

Why this approach worked:

  • Merchants could drag and drop the App Block into any section.
  • App Embed could be toggled from Theme Settings.
  • Shopify automatically handled asset hosting, versioning, and safe uninstall.

3. Solution

Step 1 – Setup

npm init @shopify/app@latest
shopify app generate extension
# Choose: Theme app extension

Step 2 – Build the App Block

blocks/product-badge.liquid

<div class="bf-product-badge" data-text="{{ block.settings.badge_text }}">
  {{ block.settings.badge_text }}
</div>

{% schema %}
{
  "name": "Product badge",
  "target": "section",
  "javascript": "widget.js",
  "stylesheet": "styles.css",
  "settings": [
    { "type": "text", "id": "badge_text", "label": "Badge text", "default": "New" }
  ],
  "enabled_on": { "templates": ["product"] }
}
{% endschema %}

Step 3 – Build the App Embed

blocks/app-embed.liquid

<div id="bf-floating-widget" hidden></div>

{% schema %}
{
  "name": "BF App Embed",
  "target": "body",
  "javascript": "widget.js",
  "stylesheet": "styles.css",
  "settings": [
    { "type": "checkbox", "id": "enable", "label": "Enable widget", "default": true }
  ]
}
{% endschema %}

Step 4 – Assets

assets/widget.js

(function() {
  document.querySelectorAll('.bf-product-badge').forEach(el => {
    el.hidden = false;
  });
  const widget = document.getElementById('bf-floating-widget');
  if (widget) widget.hidden = false;
})();

4. Results & Benefits

  • Zero code editing for merchants.
  • Lightweight & performant – assets loaded only when active.
  • Multi-language ready via Shopify’s locales/ folder.
  • Safe uninstall – no leftover Liquid snippets.

5. Key Learnings

  • Always scope CSS classes to prevent theme conflicts.
  • Use enabled_on in schema to limit block availability.
  • Leverage Shopify CLI for faster iteration and previews.

Conclusion / CTA

Theme App Extensions let you ship features faster and reduce support load by removing manual theme edits.

🚀 Looking to build a Shopify app that seamlessly integrates with any Online Store 2.0 theme? Let’s build it together and make your merchant onboarding effortless.