Related Products Shopify Application

| 4 min read

Related products recently caught my attention recently when evaluating how to best render a Product, along with what the store owner thinks are related products, hoping to increase chances of selling one or more products.

The algorithms I found published on the forums were by and large based on the following algorithm:

  • Loop through the collection.all for products
  • inside this loop:
    • Loop through all the tags the product has
    • Loop through all the tags the product from the outer collection.all loop has
    • look for any matches between tags and if one is found, render the product

Imagine for a second you have a store with 1000 products. You want to display two related products to the one you are currently showing. With this algorithm, the outer loop has to run 1000 times to provide on of each product in the store. Inside this loop, you have to loop through not only every tag the Product itself has, but also the tags each and every other Product has, looking for any matches. This is terribly inefficient. Although there are probably ways to accomplish related products without this algorithm, more than a few stores are using it.

I have an application working on Heroku that provides support for using tags to connect to related products. Try out heroku to get a sense for what it can do.

The application presented here works a little differently than the above algorithm. Once installed in your Shopify store, the application provides a link to "Manage Relates Products". Pressing this link and opening in a new tab or window, brings up the application which will work with the product specified. The application will present a simple list of any established related products if any. It accepts tags in a text box. If you submit the tags, the application will search the store for all products with a matching tag(s). These products will be assigned to a Metafield for the product. The application will display the found matching products in a list.

At this point, if you were to view the Product using the established product.liquid template, nothing would appear different at all. There is no code in place to render any related products. To take care of this, we can include a liquid snippet called "related_products" to detect if any related products are assigned to the product. If so, render some new DOM nodes, and the data representing the product. With a little javascript, we can then turn the data representing the related products into nice clickable elements.

As an example of how tagging might be used to related products to one another, I have added four records from my collection to the homepage of my store at hunkybill. I used the Ramones record as a sample product. The following figures help to explain the rationale behind the related products. Each record is tagged a different way, appropriate simply as example tags, and not necessarily for music snobs to debate. When showing the Ramones record, if I chose the tag 1970's, I would want a related record to show up, which happens to be Peter Tosh (figure 1). If I changed my mind and decided the Ramones were suggestive of Reggae, I would want Peter Tosh and Fishbone to show up as related products (figure 2).

A simple Liquid snippet that looks for the Metafield related products is good enough to render inside the product.liquid template. The DOM markup is easily styled and can be modified for almost any purpose. If you use a DOM inspector to examine related_products_data you can see the Metafield string of product data. This container div should have a style of display:none to ensure no one actually visually sees this data as it is ugly.

{% assign mf = product.metafields.related_products %}
{% unless mf == empty %}
  <div id="related_products_ct">
    <div id="related_products_data">
      {{ product.metafields.related_products.related_products }}
    </div>
    <h2>Related Products</h2>
    <ul id="related_products_list"></ul>
  </div>
{% else %}
 <p>No Related Products</p>
{% endunless %}

Once the product.liquid template and the included snippet for "related_products" has rendered, the DOM can be checked to see if any of those elements actually exist. If they do, it is simple to read the Metafield string that contains the related products into a Javascript variable. The application stored the data using JSON encoding, so we simply reverse this by parsing the string as JSON. Now we have an array of objects we can iterate, with access to anything interesting about the product. We have the images, the variants, the prices, and can therefore render a nice looking related product with nothing but CSS and some DOM elements as needed. For the purpose of this example, I have simply used a list to render a link to the related product using it's title. The simplest code to do this can be added to any shop.js file (although the dialect of this example is jQuery, it would be dead simple to use any other flavour of Javascript you like).

    (function($) {
// Product has related products
$.processRelatedProducts = function () {
var data = JSON.parse($('#related_products_data').text());
var list = $('#related_products_list');
$.each(data, function(idx, obj){
list.append($("<li>").append($("<a>").attr({href: '/products/'+obj.handle}).text(obj.title)));
});
}

})(jQuery);

$(document).ready(function() {
// DOM is loaded so we are ready to process whatever we want
if($('#related_products_data')) {
$.processRelatedProducts();
}
});

This application has plenty of room for improvement. For example, showing all the tags available like the Shopify admin uses for setting tags, limiting how many products end up as related products, searching only designated collections for products to add to related products, all easy modifications. The code for the application is open-sourced github for anyone who wants to hack away and make it better. Since some people do like to use tags to relate products, even if Shopify does not believe this is an appropriate use of tags, I hope that my application here can make at least some people happier in managing their related products.