Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Related Products by Tags — to add to product.liquid
<!-- Solution brought to you by Caroline Schnapp -->
<!-- See this: http://wiki.shopify.com/Related_Products -->
{% assign image_size = 'compact' %}
{% assign heading = 'Other fine products' %}
{% if product.tags.size > 0 %}
<h3>{{ heading }}</h3>
<ul class="related-products"></ul>
<style type="text/css">
.related-products { list-style-type:none }
{% case image_size %}
{% when 'small' %}
.related-products * { font-size:12px; text-align:center; padding:0 }
.related-products h4 { border:none; margin:10px 0 0 0; line-height:1.3 }
.related-products div.image { height:100px }
.related-products li { float:left; width:120px; height:160px; margin-right:20px }
{% when 'compact' %}
.related-products * { font-size:13px; text-align:center; padding:0 }
.related-products h4 { border:none; margin:5px 0 0 0; line-height:1.5 }
.related-products div.image { height:160px }
.related-products li { float:left; width:180px; height:220px; margin-right:25px }
{% when 'medium' %}
.related-products * { font-size:14px; text-align:center; padding:0 }
.related-products h4 { border:none; margin:10px 0 0 0; line-height:1.8 }
.related-products div.image { height:240px }
.related-products li { float:left; width:260px; height:300px; margin-right:25px }
{% endcase %}
.related-products { overflow:hidden }
.related-products span.money { font-size:0.8em }
.related-products li:last-child { margin-right:0 }
</style>
<script>!window.jQuery && document.write('<script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"><\/script>')</script>
{{ 'api.jquery.js' | shopify_asset_url | script_tag }}
<script type="text/javascript" charset="utf-8">
//<![CDATA[
var recommendations = [];
{% for tag in product.tags %}
recommendations.push('{{ tag | handle }}');
{% endfor %}
if (recommendations.length) {
var list = jQuery('ul.related-products');
for (var i=0; i<recommendations.length; i++) {
jQuery.getJSON(recommendations[i] + '.js', function(product) {
list.append('<li><div class="image"><a href="' + product.url +'"><img src="' + product.images[0].replace(/(\.jpg|\.png|\.jpeg|\.gif)/, '_{{ image_size }}$1') + '" /></a></div><h4><a href="' + product.url + '">' + product.title + '</a></h4><span class="money">' + Shopify.formatMoney(product.price, "{{ shop.money_format }}") + '</span></li>');
});
}
}
//]]>
</script>
{% endif %}
@pekeapin

This comment has been minimized.

Copy link

commented Dec 18, 2013

I am receiving duplication in the related products from this snippet - does anyone know why?
Example: http://woofnewyork.com/collections/collars/products/black-leather-dog-collar
Any help would be appreciated!! Thank you

@nadiaa

This comment has been minimized.

Copy link

commented Apr 14, 2014

Hi there. This code works really well for me. Thanks.
I was wanting to use it now on my blog articles. I have a blog category that talks about the makers of a product. I have added the associated product handle tags to the blog article, and then adapted the code above to if article.tags.size > 0 and for tags in article.tags, but it is not returning any results.
What have I missed? Thanks for any help!

@TechGirl00

This comment has been minimized.

Copy link

commented Nov 10, 2014

Two questions:

  1. Can this be made to work with collection handles as the tags and pull in the first 5 items of that collection? Currently shopify's "related items" pulls in the first 5 items of the collection that product sits in which isn't a good experience. I would like to create Collections of related items that way only 1 tag (collection handle) has to be added instead of five product handles.
  2. We already use tags in each product for other things. I'm assuming this ignores the other tags and only looks for product handles (or maybe collection handles)? OR will this only work if product handles are the only tags listed?
@mariananobre

This comment has been minimized.

Copy link

commented May 1, 2015

I solved the problem of already having other tags by including a specific handle for the related products tag. In my case I created tags in the form look-[product-handle] and then adapted the code as follows:

Replace

{% if product.tags.size > 0 %}

With

{% if product.tags.size > 0 %}
{% for tag in product.tags %}
{% assign tagArray = tag | split: '-' %}
{% if tagArray[0] == "look" %}
    {% assign look = true %}
{% endif %}
{% endfor %}
{% endif %}

{% if look %}

Replace

{% for tag in product.tags %}
  recommendations.push('{{ tag | handle }}');
{% endfor %}

With

{% for tag in product.tags %}
        {% assign tagArray = tag | split: '-' %}
        {% if tagArray[0] == "look" %}
        recommendations.push('{{ tag | replace_first: 'look-', '' | handle }}');
        {% endif %}
 {% endfor %}

Hope this helps others who might be looking for a similar solution.

@sligodavid

This comment has been minimized.

Copy link

commented Jun 24, 2015

Hi
Great piece of code. Thank you very much. Just having one problem:
How do I stop the products with the tags in them coming up when I use the search function for the product tagged?
Example. White Shirt is tagged with the handle beige-shorts because I want Beige Shorts to come up underneath as a related product. However, when I search for Beige Shorts I don't want White Shirt to come up.

@michaelrshannon

This comment has been minimized.

Copy link

commented Nov 23, 2015

This approach involves a series of ajax requests, which can lead to the rendering of products in a semi-random order (depending on the sequence in which the responses come back from the server). An alternate liquid-only approach, where each tag that references a related product is prefixed with related:, could be:

{% assign recommendations = '' %}
{% for tag in product.tags %}
  {% assign split_tag = tag | split: ':' %}
  {% if split_tag[0] == 'related' %}
    {% if recommendations != '' %}
      {% assign recommendations = recommendations | append: ',' %}
    {% endif %}
    {% assign related_handle = split_tag[1] | handle %}
    {% assign recommendations = recommendations | append: related_handle %}
  {% endif %}
{% endfor %}
{% assign recommendations = recommendations | split: ',' %}

<!-- `recommendations` liquid variable now holds an array of product handles -->
{% for product_handle in recommendations %}
  {% assign product = all_products[product_handle] %}
  <!-- Normal HTML & Liquid here, using `product` as reference to iteratee -->
{% endfor %}
@lfas23

This comment has been minimized.

Copy link

commented Nov 25, 2015

Hi, is there a way to make this responsive? for example, add in an "@include at-query" so that it maintains 3 across for tablet?

thx!

@madahmani

This comment has been minimized.

Copy link

commented Feb 20, 2016

You can make it responsive using CSS and limit the container width so it only carries a fixed amount of items.

@jmmyers29

This comment has been minimized.

Copy link

commented Apr 14, 2016

Great tutorial! And thank you mariananobre for the tip using the tags!

@hafizglotar

This comment has been minimized.

Copy link

commented May 6, 2016

please anyone help me
i want to show related product on single product page, but i could'nt. there is my code and also website link

https://luscious-cosmetics-p.myshopify.com/products/double-dazzle-lip-gloss

<script type="text/javascript" charset="utf-8"> //<![CDATA[ var recommendations = []; {% for tag in product.tags %} recommendations.push('{{ tag | handle }}'); {% endfor %} if (recommendations.length) { var list = jQuery('ul.related-products'); for (var i=0; i<recommendations.length; i++) { jQuery.getJSON(recommendations[i] + '.js', function(product) { list.append('<li><div class="image"><a href="' + product.url +'"><img src="' + product.images[0].replace(/(\.jpg|\.png|\.jpeg|\.gif)/, '_{{ image_size }}$1') + '" /></a></div><h4><a href="' + product.url + '">' + product.title + '</a></h4><span class="prod-price">' + Shopify.formatMoney(product.price, "{{ shop.money_format }}") + '</span></li>'); }); } } //]]> </script> {% endif %}

@pcross1986

This comment has been minimized.

Copy link

commented Jun 27, 2016

@Caroline this works great on a products page... But I want this to work on the cart page. How can I get this same functionality on the cart page, while still using the tag approach. Simply placing the same code on the cart page DOES NOT work since the cart could have several(more than one) item.

PLEASE CAN YOU HELP?

Again to re-specify, I need the related items to be based off the items within the cart, using their tags, and shuffle at random the 4 results. Any help would be greatly appreciated.

@ivandurst

This comment has been minimized.

Copy link

commented Jul 1, 2016

Thanks Caroline and Michael!

I added a check to see if the product has recommendation tags, and if not, display a default collection, so that this section is never empty. This is based off of @michaelrshannon's code above:

  {% assign recommendations = '' %}
  {% for tag in product.tags %}
    {% assign split_tag = tag | split: ':' %}
    {% if split_tag[0] == 'related' %}
      {% if recommendations != '' %}
        {% assign recommendations = recommendations | append: ',' %}
      {% endif %}
      {% assign related_handle = split_tag[1] | handle %}
      {% assign recommendations = recommendations | append: related_handle %}
    {% endif %}
  {% endfor %}
  {% assign recommendations = recommendations | split: ',' %}
  <!-- `recommendations` liquid variable now holds an array of product handles -->

  {% if recommendations != empty %}
    {% for product_handle in recommendations %}
      {% assign product = all_products[product_handle] %}
      <!-- Normal HTML & Liquid here, using `product` as reference to iteratee -->

    {% endfor %}
  {% else %}
    {% for product in collections.collection-title.products limit:3 %}
        <!-- Normal HTML & Liquid here, using `product` as reference to iteratee -->

    {% endfor %}
  {% endif %}
@htnhvc

This comment has been minimized.

Copy link

commented Oct 14, 2016

Hi Caroline!

Thanks so much for this snippet of code! It works perfectly but my the resolution of my images are becoming super low quality and I'm not sure why it looks like that. Can you please help me?

@zzpaul

This comment has been minimized.

Copy link

commented Dec 13, 2016

For security reason, the link in line 36 should be changed to "//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"

@mwinel

This comment has been minimized.

Copy link

commented Dec 31, 2016

Followed all the guidelines to add this to a Debut theme, unfortunately the title is displayed but the images are not. Is there a way I can go about this?

@jayrover

This comment has been minimized.

Copy link

commented Jan 3, 2017

@mwiru I have the same issue on Debut Theme

@tamara5245

This comment has been minimized.

Copy link

commented May 10, 2017

@jayrover and @mwiru
Hi, did you solve the issue with Debut Theme?

@pvanschy

This comment has been minimized.

Copy link

commented Jul 31, 2017

I have the same issue with the Debut theme, and I followed the instructions to delete image max height, which worked, following this: https://ecommerce.shopify.com/c/ecommerce-design/t/related-products-theme-debut-little-problem-448491

The images show up now which is good. However, the grid height is still restricted and there appears an annoying scroll. Any ideas on how to remove this?

@markdub111

This comment has been minimized.

Copy link

commented Sep 7, 2017

does this script comptable with sectioned theme?
not showing up in brooklyn theme.

@SalsaEzz

This comment has been minimized.

Copy link

commented Apr 1, 2018

@ivandurst I know this is a really old post but exactly what I'm looking for. Can you tell me where to put your piece of code within Caroline's?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.