Update a theme to use variant images
Variant images is a feature that allows you to associate an image with a variant. This article outlines how to update your theme to take advantage of this feature.
Updating product.liquid to support variant deep-linking
One component of the variant images feature is the ability to deep-link directly to a variant. This is done by appending the ?variant=
query parameter to the URL of the product along with the ID of the variant.
For example, if you wanted to link to the "Small" variant of a T-shirt, you could do so through a URL that looks like this:
http://example.myshopify.com/products/example-product?variant=105065082
We can use Liquid to output the attributes of the deep-linked variant when the product.liquid
template is loaded.
Selecting the variant in the option drop-down
In your theme, you may have a select menu for product options that looks like this:
<select>
{% for variant in product.variants %}
<option value="{{ variant.id }}"
>{{ variant.title }} - {{ variant.price | money }}</option
>
{% endfor %}
</select>
To have the product.liquid
template automatically select the deep-linked variant, use the following code:
<select>
{% for variant in product.variants %}
<option {% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} value="{{ variant.id }}">{{ variant.title }} - {{ variant.price | money }}</option>
{% endfor %}
</select>
Here, we are using the product.selected_or_first_available_variant attribute which returns the variant that was deep-linked. If it matches with the variant in the current iteration of the for loop, it will output selected="selected"
, causing that option in the drop-down to be selected when the template is loaded.
Showing the deep-linked variant's price
In your theme, you may be outputting the price of the variant as follows:
<div class="purchase">
<h2 class="price" id="price-preview">
{{ product.price_min | money }}{% if product.price_min <
product.compare_at_price_min %}
<del>{{ product.compare_at_price_min | money }}</del>{% endif %}
</h2>
</div>
To ensure that the price of the deep-linked variant is output, use the product.selected_or_first_available_variant attribute as shown below:
<div class="purchase">
<h2 class="price" id="price-preview">
{{ product.selected_or_first_available_variant.price | money }}{% if
product.selected_or_first_available_variant.price <
product.selected_or_first_available_variant.compare_at_price %}
<del
>{{ product.selected_or_first_available_variant.compare_at_price | money
}}</del
>{% endif %}
</h2>
</div>
Showing the deep-linked variant's image
To show the deep-linked variant's image in the "featured image" container when the product page is loaded, you must replace the product's featured image with the image of the variant returned by the product.selected_or_first_available_variant attribute.
In your theme, you may be loading the product's featured image like this:
<a href="{{ product.featured_image | product_img_url: '2048x' }}">
<img src="{{ product.featured_image | product_img_url: '2048x' }}" />
</a>
Replace this with the code below:
{% assign featured_image =
product.selected_or_first_available_variant.featured_image | default:
product.featured_image %}
<a href="{{ featured_image | img_url: '2048x' }}">
<img
src="{{ featured_image | img_url: '2048x' }}"
alt="{{ featured_image.alt | escape }}"
/>
</a>
Here, we use the product.selected_or_first_available_variant attribute to select the deep-linked variant, then access its featured_image attribute to output its image. The default
filter is used to select the product's featured_image
if a variant image does not exist.
Updating product.liquid to support variant images
In Step 1 we added Liquid code to show the appropriate attributes of the deep-linked variant. However, after the page is loaded, we must update the OptionSelectors Javascript function to update the variant image as the user selects different variants.
Updating the OptionSelectors JavaScript function
The JavaScript for OptionSelectors is typically found in the product.liquid
or theme.liquid
template. It may also be inside a separate JavaScript file in theme's Theme Assets.
Look for where OptionSelectors
is initialized, and add enableHistoryState: true
to its parameter, as follows:
new Shopify.OptionSelectors("product-select", { product: {{ product |
json }}, onVariantSelected: selectCallback, enableHistoryState: true });
Adding this new parameter to the OptionSelectors
constructor makes it so that the URL in the browser updates with the ?variant=variant_id
query parameter as you select different variants.
Next, we want to have the product page image update with the variant's image as you select different variants. In the selectCallback
function, you will likely already have some code that updates the variants' price, compare_at_price, etc. Within the selectCallback
function, add the following code:
var selectCallback = function(variant, selector) {
if (variant) {
...
if (variant.available) {
...
}
else {
...
}
}
else {
...
}
if (variant && variant.featured_image) {
var originalImage = $(".featured-image-div img");
var newImage = variant.featured_image;
var element = originalImage[0];
Shopify.Image.switchImage(newImage, element, function (newImageSizedSrc, newImage, element) {
$(element).parents('a').attr('href', newImageSizedSrc);
$(element).attr('src', newImageSizedSrc);
});
}
};
Don't forget to replace .featured-image-div
with the class or id of the element wrapping the featured image in your theme.
Preloading images
You may want to preload your images so there is no delay or flicker when they are switched. To do so, simply call this function after you have included option_selection.js
:
Shopify.Image.preload({{ product.images | json }}, '1024x1024');
Updating cart.liquid
Displaying the variant image
To display the variant image on the cart page, look for where you're outputting the featured_image
attribute of the line item variable:
<img
src="{{ item.featured_image | product_img_url: 'small' }}"
alt="{{ item.title | escape }}"
/>
... and replace it with the following:
<img src="{{ item | img_url: 'small' }}" alt="{{ item.title | escape }}" />
The img_url
filter looks for the item's variant image, otherwise it defaults to the item's featured image.
Linking to the variant
The line item title in the cart page typically links to the product page. Since the line item is aware of what variant was added to the cart, it should deep-link to the product's variant instead.
To do this, replace the product.url
attribute of the line item...
<a href="{{ item.product.url }}">
...
</a>
<!-- Output: http://example.myshopify.com/products/example-product -->
... with url
.
<a href="{{ item.url }}">
...
</a>
<!-- Output: http://example.myshopify.com/products/example-product?variant=105065082 -->