How to Add Code From Your App to a Client's Theme

add code from your app

This is a complimentary blog post to a video from the ShopifyDevs YouTube channel. In this article, Shayne Parmelee, a Developer Advocate at Shopify, will show you how to perform one of the most common tasks of Shopify developers—adding code from an app to a client’s theme when your app interacts with or adds functionality to the theme. He'll explore the two different options that are possible and highlight the benefits of both approaches.

 Shayne will walk you through how to:

  • Render background JavaScript on pages
  • Conditionally render a snippet using the content_for_header Liquid object
  • Automatically remove code with ScriptTags

Getting started

I'm here today to talk about one of the most commonly asked questions about the developer platform: how to get code from an app into a theme efficiently and easily. 

There's many different ways that people are doing this right now. I'm going to talk about two of the most common ways and which one I think is better. 

Option number one is to load our code with JavaScript. This is great for background things. It works well for something line conversion tracking. However, it’s Generally not great if you have to render content that people have to view or interact with. 

The second option—spoiler alert, this is the one we're going to be going with—is to conditionally render liquid content, based on the presence of a ScriptTag. This is great for displaying things and prevents your clients from having to remove code from their themes after the app is uninstalled because it just won't render. 

ScriptTags are remote scripts that are automatically removed when an app is uninstalled and they are really important for both of these approaches. The ScriptTag resource represents remote JavaScript code that is loaded into the pages of a shop storefront or the order status page of checkout. This lets you add functionality to those pages without modifying theme templates.

Let’s discuss the two options.

You might also like: The Shopify App CLI Tool: Build Apps Faster.

Option one: loading code with JavaScript

add code from your app: loading your code with javascript screengrab of the youtube video

On the right is an example of the Debut theme, the default theme that your users are going to have when they first open their stores. There’s nothing in the Debut theme that’s been edited yet. If I make a request to see if there are any ScriptTags, scoped to this app on this store, there aren't any, so we’ll create one. 

Creating a ScriptTag

add code from your app: screengrab of creating a scripttag section from the Youtube video

Our ScriptTag has two different things that we need to define when we're creating it.

The first is the event. In this case, we're using the onload event. This is so we can have it load on every single page. The source is scripttags.ngrok.io and you can read more about this in our docs. This is just a server that I've quickly set up in order to serve a ScriptTag. Where before, this returned an empty array. Now if I make another request, the ScriptTag has been created.

This isn't going to do a whole lot by itself, it is just an address. This needs to actually pull some JavaScript to execute on the theme. If we go to the dummy server that we've set up in Visual Studio Code, all it's doing is returning a single file, scripttag.js. Returning to our theme, we can see that this code is appropriately rendering. 

Now, this is just a little console.log, nothing is rendering yet, so we’ll take care of that next. I'm going to paste some code that I have written before. It’s very simple, with some inline styles, a box, that's just going to say this is a bar loaded with JS, and we're going to render that in the script.div, which we haven't written yet.

To create our script.div, we’re going to go into our theme, edit code, and since we want this to be rendered on all pages, we're going to add it to our theme.liquid layout. So right under the header section we're just going to say <div id=”ScriptApp”></div>.

You might also like: How to Get Reviews for Your Shopify Apps.

A note on the expected behavior of a ScriptTag

After saving that, we can see that the bar is loading in, but there's a little bit of a problem: after the rest of the page has already loaded, it’s popping in. This is an expected behavior of ScriptTags. This behavior is OK if we're doing something like conversion tracking, where the user doesn't actually need to actively interact with what's being rendered because it's just background JavaScript. That’s really what ScriptTags are meant for, but it looks kind of weird for this to be loaded in after the fact.

Some app developers have done some workarounds where they'll already render this green bar with some space and then add the text later, or have placeholder text or only fill in the parts that you need a remote call for after the remote call's been made. Any way you slice it, this is code that's running after the rest of the theme has already been rendered, so something's going to pop in at some point. 

Option two: conditionally rendering content with Liquid

The first thing that we're going to do for option number two is to add a new snippet. We'll call it script-tag-app, and this is just a little piece of code that we're going to be able to reference from our other theme file. Again, it’s just a little in-line styled bar that's going to render on the theme.

Now, the {{ content_for_header }} tag is very important. In this {{ content_for_header }} tag will be render the addresses for all of the ScriptTags for the page, so we can use that behavior in order to know whether or not the app is installed, as long as we always add a ScriptTag to the shop when the app is installed. In this case, our ScriptTag that we have created, is still here, and this is our address. 

add code from your app: conditionally rendering content with Liquid screengrab from the youtube video

We’re going to check for the presence of this ScriptTag in our {{ content_for_header }} and then conditionally render that snippet that we added. Let's just say:

{% section ‘header’ %}
{% if content_for_header contains ‘script-tags.ngrok.io’ %}
{%render ‘script-tag-app’ %}
{% endif %}

Now, if I reload the page, this is always going to be here because this is being rendered by the theme rendering engine by Liquid, rather than being rendered by a remote JavaScript call. 

The advantages of rendering through Liquid

We can also see that we're able to pull in contextual information about which page we're currently on. There's a huge amount of data that's available just through Liquid on the theme, and all of that is available through the Liquid renderer. This includes metadata that you can add to products, to the shop, or anything that you like. That metadata can also be pushed in by your themes in order for lightning-fast rendering times. 

The benefit to this now is that if we delete the ScriptTag and we refresh the page, our code has now disappeared. This has a very minimal impact on the performance of our theme because this just evaluates to false and this will never render. This avoids a situation where maybe if this piece here directly is just pasted in.

Let’s take away the conditional. In that case, if the app is uninstalled, there may still be the bar here that renders, even though the user may not be able to configure the bar anymore with your app. 

Now, we don't want the user to have to always go into the theme editor in order to add their code every time your app is installed. We’re going to look at how to do that programmatically. If we take out all of the code that we added, we can see that nothing renders. We also have no ScriptTags on the store, so this is pretty much back in the state that it started at. 

You might also like: How to Make Your Embedded Apps Load Quickly and Reliably.

The API equivalent for viewing or editing themes

The API equivalent action of looking at which themes are currently on the store is this request here, which is a request to themes.json. We can see that Debut is the only theme that's currently available, just like what's being shown in the admin. The API equivalent action for going and editing, or looking at a specific asset in a theme is this one here. So, we take the ID from the theme, we add /assets.json, and then as a query, as query parameters, we add asset[key], and then what specific asset it is that we're looking to fetch. 

In order to push the code back into our theme, we're going to make a PUT request with what we want the content to be. In this case, where we added the code was underneath this section header part of the theme. If I now search for the section header, and I input this pre-prepared little bit of code back in, then I'm going to send this PUT request. We're going to update the theme.liquid file, and if I refresh, we can see what it looks like in the editor. Perfect!

Now, obviously, this isn't going to render anything yet because we don't have our ScriptTag, but if we recreate our ScriptTag, this is now once again showing on the store. 

The same goes for our snippets: we didn't get rid of the snippet that we had made before, our ScriptTag app snippet. But if I delete this, we can see now this is going to create an error. It couldn't find the snippet, but snippets can also be created through the API, through requests like this. I refresh, and it's back.

Wrapping up on adding code to a client’s theme

Liquid is a great, very performant way to render content on the storefront, and it also has a ton of contextual information about products or about the cart or the customer that's currently logged in. There’s tons of different stuff that you can use. So, definitely use that wherever you can. Hopefully the information in this article helps you when adding code to a client’s theme.

Grow your business with the Shopify Partner Program

Learn more