The best way to display dynamic content on Shopify

How to use Shopify’s app proxy properly and for the right job

 

Dinosaur using a Shopping cart 

One day you think of an amazing idea to engage with your customers on your dinosaur memorabilia store! Display a different fun fact about their favourite dinosaur in the header of each page. You're convinced that it will increase the engagement on your Shopify store, keeping your customer browsing for longer. Your warming slippers in the shape of Stegosaurus and decorative plates featuring the mighty T-Rex will be flying off the shelves. But how can you display this type of dynamic content within your Shopify theme?

Fortunately Shopify has the solution to this dilemma, in one of its most powerful tools, the app proxy. So, you roll up your developer sleeves, or your developer’s sleeves, and get an app setup to serve all your fun facts securely through Shopify’s app proxy. But you quickly realize that while browsing the store, you spend more time seeing the Ankylosaurus loading icon than the fun facts. The app proxy seems to add significant delay to your app’s response.

While it may feel like you’ve come face to face with a T-Rex, this dinosaur sized issue can be resolved. You can use the app proxy in a more selective way to deliver a token rather than all your data.

Standard Dynamic content on Shopify

Shopify is one of the most recognizable names in the ecommerce world, and it is a title that is well deserved. One of Shopify's biggest strengths is how anyone can expand on it's out-of-the-box features with custom improvements. This gives developers and store owners total freedom over their site!

Phone on holiday
Managing your store almost feels like a vacation
photo by Mix Tape on Shutterstock

 

One of these customizable tools is Shopify’s app proxy. It allows anyone to create a secure access to a webapp of their choosing under a path on the store domain. Communication between Shopify and the webapp is secured using an HMAC signature added by Shopify’s proxy. It is worth noting that there is no constraint on the HTTP method or the type of response (HTML/CSS, javascript, image, etc.). This configuration limits the amount of CORS issues since the webapp receives a call from Shopify and not the customer’s browser. It also hides away your app’s endpoints behind Shopify’s rate limited storefront. This prevents the scraping of your precious dinosaur fun facts!

 

Diagram of the app proxy basics

 

Where the true advantage of Shopify’s app proxy comes into play is in the processing of liquid code within the app’s response. If you set the header Content-Type: application/liquid in the response, Shopify will process any liquid code you sent in the response. This liquid processing allows you to use existing data from the Shopify store without having to retrieve it in the app first. As an example, you could get the customer name or a product tag added to your app’s response through this liquid code processing.

 

Diagram of app proxy with liquid rendering

 

Where the app proxy becomes even more powerful is in its ability to be used for content gating purposes. If desired, the app can be used to check that the right customer is logged in and if a specific tag is attached to this customer. A simple if statement leads to Shopify rejecting the gated content if an unauthorized customer made the request.

{% if customer %}
    <h2>Happy 42nd birthday</h2>
{% else}
    <p><b>ERROR: You are not authorized to see this information.</b></p>
    <p>But dare I say you don't look a day over 35!</p>
{% endif %}

 

Because of the app proxy’s inherent customizable nature, the possibilities for displaying dynamic content limitless. Ever wanted to include a review system for customers with certified purchases? Maybe you’ve been moving towards a Subscription portal for your store, but can’t seem to find the right solution? Or perhaps you’ve been dreaming of implementing a customized customer wish-list. These are only some ideas that the powerful app proxy can be used for, all without having to do any manual customer authentication. Everything is handled automatically by Shopify!

The need for speed

Serving dynamic content to your store without implementing authentication sounds like a great solution. Is it too good to be true?

The flipside of this solution is the unfortunate truth that developers know all too well – the processing of liquid code takes time. Shopify needs to retrieve data from its database for your store and specific customers. In computer time that can take ages, as the processing itself is not instantaneous. Processing all of this data will slow down the delivery of the app’s response to the customer’s browser. There have been studies done to show the importance of site speed on store revenue. Amazon loses 1% in revenue for every 0.1 second added to the customer journey. Furniture Village increased their revenue by 12% simply by speeding up their page load time by 20%. Upon some self-reflection, you can probably admit you abandoned a purchase or a search for a slow load time. From these studies as well as the understanding of human behaviour, it is clear that any added delay in a shopping experience will have a cost.

As a team, we wanted to know how bad this added latency can get. We also wanted to clarify the options merchants and developers have to mitigate the risk of customers shopping elsewhere.

Our team put together a relatively simple test. We analyzed the impact on page load time when using the app proxy versus accessing an app directly without the app proxy. Our test consisted of deploying as an Azure Function a very basic app with only one endpoint returning simple data within a liquid if statement. A small Javascript code in the browser called this app both directly on its own domain and through the app proxy. The Javascript code returned the response time for each call. We took the precaution of calling the function once prior to recording the response time to avoid the Azure Function cold start.

We deployed the app in various Microsoft Azure centers around the world. This allowed us to factor in the impact from the geographical location on app response time. To calculate the added delay from using the app proxy, we subtracted the slowest response of the direct access to the app from the maximum and minimum response times of the app proxy access.

What ended up being a bit of a surprise, we observed very fast and very slow responses and nothing in between for most location. Admittedly, our sample size was too small to give a reliable proportion of fast and slow responses through the app proxy. Another issue was that the results could be time-dependent and be totally different if performed on another day or at another time of the day.

 

That being said, one trend we can pull from these tests is that the app proxy can randomly and unpredictably add a very large delay to the app’s response. In some cases edging over one second in added time. This is not insignificant when you consider that any delay of even a few hundred milliseconds can impact a store’s bottom line.

The hit-and-miss response times from the app proxy does make a case for a solution that provides direct access to the app.

Let’s speed this up!

Remember the good old days – yes, the pre-pandemic days - when a NEXUS pass holder would fast-track the never-ending security line up of your US flight thanks to their NEXUS pass while you looked with envy? The app proxy, like the NEXUS pass, requires us to put a bit of time and work upfront to reach top speed. This additional work will pay off in the form of overall faster page load time and more satisfied customers. In this solution, we will use the app proxy only to securely deliver a token to the browser. From that point the token can then be used to authenticate all the connections from the browser directly to the app, bypassing the slower app proxy.

The token string can be passed within a Liquid if statement. It will verify if the customer is logged in with the expected customer ID or if the customer’s account has a specific tag. If the required Liquid condition is not met, the token would be removed from the response sent to the customer’s browser.

 Diagram showing how to serve and use a JWT token using Shopify's app proxy

The first call delivering the token to the authenticated customer will indeed suffer from the app proxy delay. However, this is why the token expiration time should be set wisely and in consideration of the typical customer session duration. While this expiration time can be customized, it should not be omitted. The token is a key providing access to all the data that this customer has access to on your app.

There is more time required in development of this solution. You have to create a token for each customer and validate this token for every single API call to your app. But once the development is done and the token is delivered, you are completely in control of the loading time for your app’s data!

How does it look in practice?

So, you want to take your store to the next level, and you have a hunch that if your customers would love to create their own wish lists. Ensuring privacy of each customer’s list is paramount. We need to configure the wish list so that only the customer can access their own wish list. Imagine you were putting together a wish-list for the holidays. You wouldn’t want your kids to find out that their Triceratops onesie came from an online store and not Santa!

Let’s use a standard token in the form of a JWT (Javascript Web Token). Since we cannot revoke a JWT, we’ll use a 5 minute expiration time to protect the customers wish-list.Typically once a customer has logged in they go straight to their wish-list page. With our solution upon this action a request will be sent to the app proxy URL, for example at

GET https://dinos-are-cool.myshopify.com/apps/special-app/jwt?customer_id=123456789

From here, we need the customer ID to know who is trying to authenticate the request. We use the customer ID in the app response to make sure that only the logged-in customer with this ID can get the token for this account.

A convenient way to pass the JWT is to have a JSON response with the Liquid veto removing the secured field. This way, the browser can retrieve the token only through an API call before loading the data from your app directly.

{
    {% if customer.id == 123456789 %}
        "token": "eyJhbGczI1NiJ9.SW4gUlNBIHN0IQ.IRMQENi4yp4er2L"
    {% endif %}
}

The app proxy will always return a JSON in the response. The webpage requesting the token should handle the missing ”token” field as an unauthorized cell.

The wish-list page can then request the wish-list data from using an API call to your app directly, passing the JWT in the call headers to be validated in the app. Similarly, an “add to my wish-list” button on a product page would send a POST request to your wish-list app with the token above in the headers. At that point, you are truly free to implement anything you want without worrying about account management.

Conclusion

Shopify’s app proxy is a powerful tool that unlocks a lot of potential for online store owners. However, it needs to be used carefully as it does add latency to page load time, and anyone of the digital age knows how important a fast load time is. Returning a token to allow for a direct and secure access to the app is ideal to get around the potential for large added latency. However you are better off using only the app proxy for apps called once or twice per session since you have to do one app proxy call to retrieve the token.

Combining the app proxy with one of the numerous modern serverless services available provides a scalable way for anybody with some small development resources to customize their Shopify store. Create a feature totally unique to your store, making you stand out! Even in the extremely competitive industry of dinosaur memorabilia.