Shopify Tutorial: Associating Product Variants with Product Images

UPDATE 11/10/2012: There is now an official, non-hacky solution for associating variants and product images! Check out the Variant Images app by the awesome Blake Mesdag and Mark Dunkley ๐Ÿ™‚

In this tutorial I’ll be showing you how to associate product variants with product images using jQuery and Shopify’s new feature for adding unique alt tags for product images. For demonstration purposes I’m going to be modifying one of Shopify’s free themes, Radiance, but this technique will work with any theme. You can check out demos of this in action here (single option) and here (multiple options).

The screenshot below shows what the Radiance’s theme looks like initially. The first thing we’re going to do is set up the product’s variants and alt tags. After that, we hide the #thumbs <ul>. Finally, we’re going to add some Javascript to make it so that the options dropdown in the top-right corner changes the image inside the #active-wrapper div with the appropriate product image. For example, if you select “Black” for colour, #active-wrapper will show the product image with the black shirt.

Radiance theme’s default product page.

Sounds easy, right? Let’s get started!

1. Set up your product variants and product image alt tags.

The first thing you must do is match up your product’s variants with your product image’s alt tags. In order for this to work, the product’s variants must be exactly the same as the product image’s alt tags. The screenshot below shows you an example of a proper setup.

It’s important to note that you can only make a product association with one option. You can certainly have up to three options for your product (for example, I added a “Size” option here), but only one will affect what product image is shown. In step 3, you’ll see how to choose which option is tied to the product images.

variants and product image alt tags

An example of a proper variants and alt tag setup.

2. Hide the thumbnails (optional)

The next step is to hide the thumbnails with CSS. This step is optional, but to me it makes sense to hide them because the variant-selecting dropdown should be the only thing that controls what’s shown as the main image.

To do this in the Radiance theme, I simply added the existing “hidden” class to the <ul> that contains all of the thumbnails, as shown below. It’s important to still output the images (although they won’t be visible) because 1) we can pre-load the images and 2) we need to grab the ‘src’ attribute of the images when we swap the main image inside #active-wrapper.

I’m also going to change the product_img_url value inside the <img&rt; tag from ‘thumb’ to original, so that we load the biggest possible product image inside #active-wrapper. In reality you can strip out a lot more of the code below, but for the purpose of this tutorial I’m just going to keep it as is.

<ul id="thumbs" class="hidden">
  {% for image in product.images %}
     <li class="{% if forloop.first %} first{% endif %}{% if forloop.last %} last{% endif %}">
       <a class="gallery" rel="product-gallery" href="{{ image | product_img_url: 'original' }}">
          <img src="{{ image | product_img_url: 'original' }}" alt="{{ image.alt | escape }}" />
       </a>
     </li>
  {% endfor %}
</ul>

Your product page should now look like this:

No thumbnails!

2. Look for the selectCallback function

If you’re using a theme from the Shopify Theme Store, the chances are high that it is using the OptionSelector javascript. This means that the theme contains a function called selectCallback.

The selectCallback function is called whenever a user selects a different option through the options dropdown menu, and it’s used to update the variant’s price and Compare At price. Since the image-swapping needs to happen when the user selects a different option, why not place our JS in selectCallback? ๐Ÿ˜€

What you can do is place the code in the Step 3 inside the selectCallback function, which is usually located in “product.liquid” or “theme.liquid”. In Radiance, it is located at the bottom of “theme.liquid”.

What if your theme does not use OptionSelector? Worry not, there are other solutions. Your theme may be using a dropdown menu or radio buttons for single-option products. In that case, you can use jQuery’s change() method instead to trigger the Javascript code in Step 3.

3. Add some code to selectCallback

Paste the code marked in blue. The first bit of Liquid goes outside of the selectCallback function. Everything below “//Swapping images JS” goes inside the selectCallback function.


{% assign option_to_match = 'Your Option Name Here' %}
{% assign option_index = 0 %}
{% for option in product.options %}
  {% if option == option_to_match %}
    {% assign option_index = forloop.index0 %}
  {% endif %}
{% endfor %}


 <script>
    var selectCallback = function(variant, selector) {
    
     //Swapping images JS
    var optionValue = variant.options[{{ option_index }}];
    var imageSrc = $("#thumbs img[alt='"+optionValue+"']").attr('src');
    if (imageSrc != 'undefined') {
      //Change '_thumb' with the image size that you are using for the thumbnails
      imageSrc = imageSrc.replace('_thumb','');
      $('#active-wrapper img').attr('src', imageSrc);
    }    
    
...rest of selectCallback code

If your code does not use selectCallback, what you could do is use jQuery’s change() method to check for when the option for the dropdown is changed. The code would look something like the code below, where ‘#selector’ (marked in blue) is the id of the select dropdown or radio buttons.

 
{% assign option_to_match = 'Your Option Name Here' %}
{% assign option_index = 0 %}
{% for option in product.options %}
  {% if option == option_to_match %}
    {% assign option_index = forloop.index0 %}
  {% endif %}
{% endfor %}
<script>

//Swapping images JS
$('#selector').change(function() {
    var optionValue = variant.options[{{ option_index }}];
    var imageSrc = $("#thumbs img[alt='"+optionValue+"']").attr('src');
    if (imageSrc != 'undefined') {
      //Change '_thumb' with the image size that you are using for the thumbnails
      imageSrc = imageSrc.replace('_thumb','');
      $('#active-wrapper img').attr('src', imageSrc);
    }    
});
</script>

First, what we need to do is set what option we want to associate with product images. This is done by changing the value of the ‘option_to_match’ variable, marked in red in the above code snippets. In this tutorial’s example, options_to_match would be “Color”, because that’s the name of the option for our variants. The Liquid code does a forloop to save the index number of the chosen option which is then used in the following Javascript snippet. Big thanks to Caro for this Liquid snippet, as without it this technique would only work for single-option products.

What the Javascript code does is it saves the variant title of the selected variant in the dropdown inside a variable, and then looks for the product image inside #thumbs that has the same alt tag as the value of the variable. Once it finds the matching product image, it takes the value of the src attribute of the matching image and places it inside the src value of the image that’s currently inside #active-wrapper.

Conclusion

That’s all there is to it! If you’re having trouble, make sure that you have set up the product alt tags and variant titles correctly, as outlined in Step 1. Please leave a comment if you have any questions or feedback!

UPDATE: I received some feedback from my peers, and it really makes no sense to limit this to one option. For example, for shirts it makes sense to have the colour and another option for size. I will be updating this article tonight to address this.

UPDATE 2: The code now supports multiple options thanks to the help of the incredible Caroline Schnapp!

UPDATE 3:Made some big fixes – sorry for the confusion guys. Also fixed a silly variable naming mistake. Thanks Czarto for catching that!

51 comments

Leave a Reply: