How to add content to a Shopify template through the Shopify Asset API

At times it makes sense to have your Shopify app update a store's templates. Two frequent cases I've seen are:

  1. A public or unlisted app needs to add something like a JavaScript file to the Shopify frontend and they don't want to ask their merchants to do it by hand.
  2. A merchant needs to update a piece of content on the frontend dynamically (like for a sale), but liquid isn't powerful enough to do it.

The Shopify Asset API

Luckily Shopify has an API that you can use to update a store's templates, called the Asset API.

The Asset API is a standard REST API though it has a merged create/update actions (PUT is used in place of POST). This means you can modify the theme's liquid files through the API by finding and updating the asset files.

The biggest complication I see is that an entire template is replaced, when you only wanted to add to it. Here's how I solved it.

Adding Liquid code to Shopify via Asset API

One of my Shopify apps adds a block of JavaScript to the main layout. The code for this update is as follows:

asset = ShopifyAPI::Asset.find('layout/theme.liquid') # 1.
# Grab a cache of the pre-installed layout
self.theme_layout = asset.value # 2.
snippet = DripSnippet.new(self.drip_account)
if asset.value.match(/#{snippet.start_wrapper}/i) # 3.
  asset.value.sub!(/#{snippet.start_wrapper}.\*#{snippet.end_wrapper}/im, snippet.snippet) # 4.
else
  asset.value.sub!(/<\\/body>/, "#{snippet.snippet}") # 5.
end
return asset.save # 6.

There are six points to highlight.

  1. First find the asset by name in the store's Shopify theme. This is just like any other ShopifyAPI find method but notice that the resource identifier is the asset path in the theme.

  2. Copy the current template content and save it to the Shop model (not shown in this snippet). This is done to have a backup copy of the asset saved to the app just in case.

  3. Check to see if the JavaScript snippet is in the asset already. The start_wrapper method is just the unique string that the app uses as a boundary marker.

  4. If the snippet already exists, replace it by using a Regex. Effectively this means to replace everything between the start_wrapper and end_wrapper with the content from the snippet (which includes the wrappers too).

  5. If the snippet doesn't exist, add it to the end before the closing body tag.

  6. Save the asset back to Shopify via the PUT API call and return the response to the caller.

Potential drawbacks of this method

The second step is extremely important and should be mentioned again.

Since the app is dynamically changing the template used on the store, we need to make sure to save a backup copy of it in case something goes wrong. As you can see in the 3rd, 4th, and 5th steps the code to replace or add the JavaScript snippet is complex. Without a solid test suite and the backup copy, the app could accidentally replace the wrong code in the template and cause all sorts of issues.

For this app, the worst case is that the JavaScript snippet gets added twice. Based on how it works, nothing harmful will happen in this scenario, but you will need to think about the impact of your specific change and what would happen if it's added multiple times.

How things could happen in your Shopify store

While complex, dynamically replacing content in a Shopify template can be really powerful.

As an app owner, you can ensure that all of your merchants fully install any frontend code needed without forcing them to do it manually. This is a huge time saver for your merchants and can speed up the benefits they receive from your app.

As a merchant with a private app, you can easily create dynamic pieces of content throughout your site that you swap in and out. It's even possible to do this logically, for example to promote today's best selling item until stock levels drop below a limit and then promote something else. With the right logic and great content, you could really improve your store's content.

Using Liquid include instead

One final recommendation if you're going to be adding complex snippets of text or Liquid code to your Shopify theme. It'd be better to instead add that code to a Shopify Liquid snippet and only use the Regex to add the Liquid include function.

That way you can just replace the Liquid snippet file all at once and only need the complex Regex for the initial install.

Whatever the purpose, don't be afraid of using a Shopify app to dynamically add content to your store.

Eric Davis

Would you like to get a daily tip about Shopify?

Sign up for Eric's Daily Shopify Tips to get my daily email with a tip for Shopify every morning.

Each tip includes a way to improve your store: customer analysis, analytics, traffic, SEO, customer acquisition, Rich Results, CRO... plus plenty of puns and amazing alliterations.

Plus you'll get free access to my Premium Resource Center for free.

Join 4,400+ other Shopify store owners and sign up before the next tip is sent.

I won't send you spam. Unsubscribe at any time. Powered by ConvertKit

Topics: Shopify api Shopify app Shopify asset Shopify development

Would you like a daily tip about Shopify?

Each tip includes a way to improve your store: customer analysis, analytics, customer acquisition, CRO... plus plenty of puns and amazing alliterations.