Sign up to Gadget

How to work with Shopify Themes as an App Developer (Part 2): Embedding your frontend



Learn about the different approaches available for embedding your app's user interface into the Shopify Admin.




How to work with Shopify Themes as an App Developer (Part 2): Embedding your frontend

Mircea Piturca
March 3, 2023

Two weeks ago, we covered the differences between themes built on Shopify’s Storefront 1.0 and 2.0 theme editor, and how to detect them programmatically.

Next, we’ll talk about the different ways to embed functionality on the storefront, and verify that it works.

App blocks, app embeds, and custom code injection

At a high level, there are three ways to inject your app’s user interfaces and functionality on top of a merchant’s theme, each with their own challenges and limitations:

Manual code injection

Often, on storefront 1.0 themes, the only way for a developer to present their application's user interface on a merchant's store is to ask the merchant to paste a snippet of code into their theme, by hand. To enable this, app developers will often design an onboarding screen that is presented to the merchant upon app installation. While this approach is not ideal, it is a necessary evil as a result of 1.0 theme limitations.

Painful process.

As you can imagine, asking non-technical merchants to copy/paste code is a daunting, cumbersome, and error-prone process. Merchants, and app developers alike, will often cite this process as the biggest source of frustration, bugs, and customer support tickets.

To alleviate this issue, Shopify announced app blocks, and app embeds with the aim of giving app developers a more automated way of injecting their functionality onto a site, without burdening the merchant.

App embeds

App embeds, which work for both 1.0 and 2.0 themes on Shopify, address some of the issues presented by the code injection approach, by allowing app developers to programmatically inject limited functionality to the theme. In general, app embeds can be used in only two circumstances:

  • When the app’s functionality has no user interface. E.g. a tracking script that produces analytics reports might need to be installed on a theme in order to run, but does not actually present the shopper with a user interface.
  • When the user interface is limited to being presented as an overlay. E.g. a popup chat window that is presented over the theme.

As a result of these limitations, app embeds cannot be used in many of the popular use cases you might have. For example, if you wanted to display product reviews directly on a product page, as opposed to a popup presented on top of the product page, you wouldn't be able to do so with app embeds.

App blocks

With the introduction of 2.0 themes, Shopify apps now have the ability to inject "blocks" of functionality. These can be integrated as entire sections of a theme, or as individual blocks within those sections. This allows you, the app developer,  to include your app’s functionality precisely where you need it on a page. App blocks also come with the benefit of being merchant-friendly. Each app block you inject on a theme can be modified, added, removed, or repositioned on the theme, directly by the merchant, with no coding experience required by leveraging Shopify’s built-in storefront editor.

The benefits of injecting user interfaces via app blocks are numerous:

  • There is little room for human error as merchants are not copy/pasting code into their themes, which can be error-prone and confusing.
  • The merchant is given a high degree of optionality and flexibility with regards to the positioning of app blocks on their website, and can modify how an app block is presented in limited, but powerful ways, without the need for a developer.

However, injecting app blocks is only possible on Storefront 2.0 themes.

Which approach is right for your application?

To summarize, there are three ways to inject user interfaces and functionality into Shopify themes. However, each one comes with limitations:

  • Asking merchants to inject custom code into their theme will work for both 1.0 and 2.0 themes, and can support any type of interface or functionality. However, as previously stated, this approach is manual, cumbersome and incredibly prone to user error.
  • Embedding your functionality via app embeds is a great option as it applies to both 1.0 and 2.0 themes, but this approach can only be used when the application has no user interface, or the user interface is presented strictly as a popup on top of the theme.
  • App blocks are the most fully-featured approach to injecting user interfaces on a store, giving merchants a great onboarding experience and some no-code customization options. They are, however, limited to 2.0 themes.

When deciding on which tactic to use for my applications, I generally use the following rule of thumb:

  • If the app I’m building has no user interface or the user interface can be displayed as a popup, then I use app embeds because it works for both 1.0 and 2.0 themes, and does not require giving the merchant any code injection instructions.
  • If the app I’m building has a user interface that cannot be displayed as a popup, then I have no choice but to combine the use of app blocks for merchants with 2.0 themes, and code injection steps for merchants with 1.0 themes.

How to verify that a merchant has enabled your application on their storefront

Regardless of the approach you take, you’ll often want to programmatically verify that a merchant has successfully completed the setup of your application, including any parts that must be enabled on the storefront theme. You may want to do this for a few reasons:

  • To stop showing setup instructions to the merchant once the setup has been completed.
  • To track (analytics) where merchants drop off during onboarding, and what percentage of them fail to gain the benefits of your application because they never set it up correctly.

To detect whether a merchant has enabled your user interface, you can parse the theme and look for your application's code.

Detecting manual code injection and app blocks

As mentioned earlier, because app blocks and manual code injections are limited to working on a subset of themes, they must often be combined by app developers who wish to have their applications installed by all merchants on the platform, regardless of the theme decisions they've made.

To detect if your manual code instructions, or app blocks have been installed on a theme, you can create a custom API Action in Gadget on your Themes model that runs a script.

To do this, go to the <inline-code>shopifyTheme<inline-code> model in your Gadget app and click the "+" sign next to Actions. Name the new action’s API identifier <inline-code>refreshInstallState<inline-code>. Replace the action's code with the following:

This file parses the theme and looks for code snippets or app block names that match our application's user interface. Should it find that our custom code instructions for 1.0 themes have been followed and that the UI has been enabled, it will set a boolean field called <inline-code>hasLiquidInjected<inline-code> (that we've added to our Theme model) to true. Similarly, if our app block's name is detected, we set the boolean field titled <inline-code>hasAppBlockInstalled<inline-code> to <inline-code>true<inline-code>.

By creating a custom Action in Gadget, we give ourselves the ability to run this check at any time from our application's frontend or backend, with a single API call. For example, we can choose to verify that our app is properly installed every time the merchant attempts to log into our application, and leverage the results of our API call to determine whether to continue to present them with installation instructions. We can also choose to run this Action on a scheduler, periodically verifying that our app continues to be properly installed, and sending notifications to merchants should there be an issue. To do that, we would have added our file to a Global Action in Gadget, with a scheduler as a trigger.

Detecting app embeds

If our application's UI can be submitted to Shopify as an app embed, we can verify that it has been correctly installed by parsing the theme for the app embed's name.

To do this, the instructions are the same as for how we added a code file for detecting app blocks and manual code injections above. Go to the shopifyTheme model in your Gadget app and click the "+" sign next to Actions. Name the new action’s API identifier refreshInstallState. Replace the action's code with the following:

In this case, should we detect that our app embed is enabled, we set a boolean field called <inline-code>hasAppBlockInstalled<inline-code> to true.

Shopify themes don’t have to be daunting

Whether you’re working with 1.0 or 2.0 themes, there’s always a way to get your app’s user interface in front of shoppers: be it, asking the merchant to inject code into their theme manually, or by leveraging app embeds and app blocks. And by hooking your logic off of Gadget’s built-in Actions, you can quickly build out the backend needed to programmatically deploy, and verify your app’s interface has been successfully implemented on a store.
I hope these tips and tricks help you navigate interacting with Shopify themes on your next project.

About the author

Mircea is a freelance software developer, passionate about accessibility and performance. He helps clients of all sizes, building accessible and performant online experiences. You will find him blogging, sharing tips, and code on his website Sections.Design.

Interested in learning more about Gadget?

Join leading agencies making the switch to Gadget and experience the difference a fullstack platform can make.
Keep reading to learn about how it's built

Under the hood

We're on Discord, drop in and say hi!
Join Discord
Bouncing Arrow