Shopify themes, liquid, logos, and UX
Hello,
I'm wondering if anyone has been succesful in modifying the Debut theme to show multiple images (with identical alt tag) per product variant? Right now I have three variants for one product, and each variant consists of three photos. I would only like to display the three relevant photos per variant as opposed to all nine.
I've seen many previous posts, but some of the methods seem outdated or not applicable to the Debut theme.
Thanks,
Gavin
Hi Gavin,
Check below URL, Tutorial for Multiple images per variant:
https://shopify-tutorials.myshopify.com/blogs/tutorials/15665261-grouping-images-with-variants
I hope it will help you a lot.
Hi,
For new themes like Debut, this may be helpful: Grouping images with color variants - Debut Theme
CAUTION: If you have a newer version of Debut such as V16, the code the guide specifies inside product-template.liquid no longer exists as there were changes to that theme to support video and 3D models. Not sure if anyone has come up with a version of this guide that will work with the newer updated version of Debut. If you know of one, I would love to hear about it.
Hi I have the same issue right now. My theme is Turbo Dubai. Please I need help.
Hello GUys,
We have built an app for this specific use case.
Have a look at it here.
https://apps.shopify.com/easy-variant-images
-Ankit
I don't think that anybody ask for a app... ^^
If anybody want use an app, there are other apps with less costs for the functionality with multiple image for variants...
If somebody have an idea how to solve, in this case as example; give all images of a variant the same alt text, and then filtering all images of a product based on the alt text of the images/media. Hide all images onload, than show all images with the same alt text depends on the selected option in the dropdown menu.
I am new in liquid and the syntax, but I would say should be not so difficult in plain javascript & html...
would be great if a experienced shopify developer can help or give an idea how to solve or find a solution...
Many thanks in advance...
I'm looking for the same solution and found this video which might help: https://www.youtube.com/watch?v=ARpSIscriYA
@ianjh thanks for your reply...
I know this video guide, follow the steps, but I think something in the liquid code is changed from shopify, so that the result is not the same like in the video...
When you look into the comments from the youtube-video, last comment from hayadatube, its me, I ask for an update, but till now, no reply... instead of answering the nice guy is posting commercial..
The tutorials from this guy are great, I love them... but would be much greater If Jan would update the video...
Ah ok, sorry. I hadn't tried it yet.
I'll keep looking and post here if I find a solution.
Have you find any solution for these?
yay! let's all pay for something that should come default in shopify!
Hi, I know this is an old issue and hope you already found the solution to the problem. I will leave an answer for people who are coming from search. We recently built Rubik Variant Images app which is solving problem of displaying only relevant variant images.
I also recorded a video showing how to set-up the app.
I was able to get the respective variant images to show, and selecting from the drop down menu changes the primary variant image.
Two things I noticed:
1. The secondary and tertiary images do not update when switching variants.
2. Reselecting the default variant doesn't update any image at all.
Would anybody be able to clarify?
product.liquid page
{% section 'product-template' %}
<script>
// Override default values of shop.strings for each template.
// Alternate product templates can change values of
// add to cart button, sold out, and unavailable states here.
theme.productStrings = {
addToCart: {{ 'products.product.add_to_cart' | t | json }},
soldOut: {{ 'products.product.sold_out' | t | json }},
unavailable: {{ 'products.product.unavailable' | t | json }}
}
</script>{% include 'pagefly' %}
<script>
jQuery(document).ready(function($){
var images = [];
{% for image in product.images %}
images.push({url: "{{ image | product_img_url: 'medium' }}", alt: "{{ image.alt }}"});
{% endfor %}
var thumbnails = $(".thumbs");
$('#product-select-option-0').change(function() {
var selected = $(this).val(), mainImage = jQuery('.featured img').attr('src').replace('_1024x1024', '_medium');
thumbnails.hide().html("");
arr = [];
var addImage = $.each( images, function( i, image ) {
var alt = images[i].alt, url = images[i].url;
if (alt == selected || url == mainImage) {
thumbnails.append('<div class="image span2"><a href="' + url.replace('_medium', '_1024x1024') + '" data-original-image="' + url.replace('_medium', '_1024x1024') + '"><img src="' + url + '" alt="' + alt + '"></a></div>');
}
});
arr.push(addImage);
$.when.apply($, arr).done(function () {
thumbnails.fadeIn();
$('#product .thumbs a').on('click', function(e) {
e.preventDefault();
switchImage($(this).attr('href'), null, $('.featured img')[0]);
});
});
});
});
</script>
product-template.liquid
<div class="product-template__container page-width" itemscope itemtype="http://schema.org/Product" id="ProductSection-{{ section.id }}" data-section-id="{{ section.id }}" data-section-type="product" data-enable-history-state="true">
<meta itemprop="name" content="{{ product.title }}">
<meta itemprop="url" content="{{ shop.url }}{{ product.url }}">
<meta itemprop="image" content="{{ product.featured_image.src | img_url: '800x' }}">
{% comment %}
Get first variant, or deep linked one
{% endcomment %}
{%- assign current_variant = product.selected_or_first_available_variant -%}
{%- assign product_image_zoom_size = '1024x1024' -%}
{%- assign product_image_scale = '2' -%}
{%- assign enable_zoom = section.settings.enable_zoom -%}
{% case section.settings.image_size %}
{% when 'small' %}
{%- assign product_image_width = 'medium-up--one-third' -%}
{%- assign product_description_width = 'medium-up--two-thirds' -%}
{%- assign product_thumbnail_width = 'medium-up--one-third' -%}
{%- assign height = 345 -%}
{% when 'medium' %}
{%- assign product_image_width = 'medium-up--one-half' -%}
{%- assign product_description_width = 'medium-up--one-half' -%}
{%- assign product_thumbnail_width = 'medium-up--one-quarter' -%}
{%- assign height = 530 -%}
{% when 'large' %}
{%- assign product_image_width = 'medium-up--two-thirds' -%}
{%- assign product_description_width = 'medium-up--one-third' -%}
{%- assign product_thumbnail_width = 'medium-up--one-fifth' -%}
{%- assign height = 720 -%}
{% when 'full' %}
{%- assign product_image_width = '' -%}
{%- assign product_description_width = '' -%}
{%- assign product_thumbnail_width = 'medium-up--one-eighth' -%}
{%- assign height = 1090 -%}
{%- assign enable_zoom = false -%}
{% endcase %}
<div class="grid product-single">
<div class="grid__item product-single__photos {{ product_image_width }}{% if section.settings.image_size == 'full' %} product-single__photos--full{% endif %}">
{%- assign featured_image = product.selected_or_first_available_variant.featured_image | default: product.featured_image -%}
{% for image in product.images %}
{% capture img_id %}FeaturedImage-{{ section.id }}-{{ image.id }}{% endcapture %}
{% capture img_class %}product-featured-img{% endcapture %}
{% capture zoom_img_id %}FeaturedImageZoom-{{ section.id }}-{{ image.id }}{% endcapture %}
{% capture img_wrapper_id %}{{ zoom_img_id }}-wrapper{% endcapture %}
{%- assign img_url = image | img_url: '1x1' | replace: '_1x1.', '_{width}x.' -%}
{% include 'image-style' with small_style: true, width: height, height: height, wrapper_id: img_wrapper_id, img_id: img_id %}
<div id="{{ img_wrapper_id }}" class="product-single__photo-wrapper js">
<div id="{{ zoom_img_id }}" style="padding-top:{{ 1 | divided_by: image.aspect_ratio | times: 100}}%;" class="product-single__photo{% if enable_zoom %} js-zoom-enabled{% endif %}{% if product.images.size > 1 %} product-single__photo--has-thumbnails{% endif %}{% unless featured_image == image %} hide{% endunless %}" data-image-id="{{ image.id }}"{% if enable_zoom %} data-zoom="{{ image | img_url: product_image_zoom_size, scale: product_image_scale }}"{% endif %}>
<img id="{{ img_id }}"
class="feature-row__image {{ img_class }} lazyload{% unless featured_image == image %} lazypreload{% endunless %}"
src="{{ image | img_url: '300x300' }}"
data-src="{{ img_url }}"
data-widths="[180, 360, 540, 720, 900, 1080, 1296, 1512, 1728, 2048]"
data-aspectratio="{{ image.aspect_ratio }}"
data-sizes="auto"
alt="{{ image.alt | escape }}">
</div>
</div>
{% endfor %}
<noscript>
{% capture product_image_size %}{{ height }}x{% endcapture %}
<img src="{{ featured_image | img_url: product_image_size, scale: product_image_scale }}" alt="{{ featured_image.alt }}" id="FeaturedImage-{{ section.id }}" class="product-featured-img" style="max-width: {{ height }}px;">
</noscript>
{% if product.images.size > 1 %}
{% if product.images.size > 3 %}
{%- assign enable_thumbnail_slides = true -%}
{% endif %}
<div class="thumbnails-wrapper{% if enable_thumbnail_slides == true %} thumbnails-slider--active{% endif %}">
{% if enable_thumbnail_slides == true %}
<button type="button" class="btn btn--link medium-up--hide thumbnails-slider__btn thumbnails-slider__prev thumbnails-slider__prev--{{ section.id }}">
{% include 'icon-chevron-left' %}
<span class="icon__fallback-text">{{ 'sections.slideshow.previous_slide' | t }}</span>
</button>
{% endif %}
<ul class="grid grid--uniform product-single__thumbnails product-single__thumbnails-{{ section.id }}">
{% assign featured_alt = product.selected_or_first_available_variant.option1 %}
{% for image in product.images %}
{% if image.alt == featured_alt or image == featured_image %}
<li class="grid__item {{ product_thumbnail_width }} product-single__thumbnails-item js">
<a href="{{ image.src | img_url: product_image_zoom_size, scale: product_image_scale }}"
class="text-link product-single__thumbnail product-single__thumbnail--{{ section.id }}"
data-thumbnail-id="{{ image.id }}"
{% if enable_zoom %}data-zoom="{{ image.src | img_url: product_image_zoom_size, scale: product_image_scale }}"{% endif %}>
<img class="product-single__thumbnail-image" src="{{ image.src | img_url: '110x110', scale: 2 }}" alt="{{ image.alt | escape }}">
</a>
</li>
{% endif %}
{% endfor %}
</ul>
{% if enable_thumbnail_slides == true %}
<button type="button" class="btn btn--link medium-up--hide thumbnails-slider__btn thumbnails-slider__next thumbnails-slider__next--{{ section.id }}">
{% include 'icon-chevron-right' %}
<span class="icon__fallback-text">{{ 'sections.slideshow.next_slide' | t }}</span>
</button>
{% endif %}
</div>
{% endif %}
</div>
<div class="grid__item {{ product_description_width }}">
<div class="product-single__meta">
<h1 itemprop="name" class="product-single__title">{{ product.title }}</h1>
{% if section.settings.show_vendor %}
<p itemprop="brand" class="product-single__vendor">{{ product.vendor }}</p>
{% endif %}
<div itemprop="offers" itemscope itemtype="http://schema.org/Offer">
<meta itemprop="priceCurrency" content="{{ shop.currency }}">
<link itemprop="availability" href="http://schema.org/{% if product.available %}InStock{% else %}OutOfStock{% endif %}">
<p class="product-single__price product-single__price-{{ section.id }}{% unless current_variant.available %} product-price--sold-out{% endunless %}">
{% if current_variant.compare_at_price > current_variant.price %}
<span class="visually-hidden">{{ 'products.product.regular_price' | t }}</span>
<s id="ComparePrice-{{ section.id }}">{{ current_variant.compare_at_price | money }}</s>
<span class="product-price__price product-price__price-{{ section.id }} product-price__sale product-price__sale--single">
<span id="ProductPrice-{{ section.id }}"
itemprop="price" content="{{ current_variant.price | divided_by: 100.00 }}">
{{ current_variant.price | money }}
</span>
<span class="product-price__sale-label product-price__sale-label-{{ section.id }}">{{ 'products.product.on_sale' | t }}</span>
</span>
{% else %}
<span class="visually-hidden">{{ 'products.product.regular_price' | t }}</span>
<s id="ComparePrice-{{ section.id }}" class="hide">{{ current_variant.compare_at_price | money }}</s>
<span class="product-price__price product-price__price-{{ section.id }}">
<span id="ProductPrice-{{ section.id }}"
itemprop="price" content="{{ current_variant.price | divided_by: 100.00 }}">
{{ current_variant.price | money }}
</span>
<span class="product-price__sale-label product-price__sale-label-{{ section.id }} hide">{{ 'products.product.on_sale' | t }}</span>
</span>
{% endif %}
</p>
<form action="/cart/add" method="post" enctype="multipart/form-data" class="product-form product-form-{{ section.id }}{% unless section.settings.show_variant_labels %} product-form--hide-variant-labels{% endunless %}" data-section="{{ section.id }}">
{% unless product.options.size == 1 and product.variants[0].title == 'Default Title' %}
{% for option in product.options_with_values %}
<div class="selector-wrapper js product-form__item">
<label {% if option.name == 'default' %}class="label--hidden" {% endif %}for="SingleOptionSelector-{{ forloop.index0 }}">
{{ option.name }}
</label>
<select class="single-option-selector single-option-selector-{{ section.id }} product-form__input" id="SingleOptionSelector-{{ forloop.index0 }}" data-index="option{{ forloop.index }}">
{% for value in option.values %}
<option value="{{ value | escape }}"{% if option.selected_value == value %} selected="selected"{% endif %}>{{ value }}</option>
{% endfor %}
</select>
</div>
{% endfor %}
{% endunless %}
<select name="id" id="ProductSelect-{{ section.id }}" data-section="{{ section.id }}" class="product-form__variants no-js">
{% for variant in product.variants %}
{% if variant.available %}
<option {% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} value="{{ variant.id }}">
{{ variant.title }}
</option>
{% else %}
<option disabled="disabled">{{ variant.title }} - {{ 'products.product.sold_out' | t }}</option>
{% endif %}
{% endfor %}
</select>
{% if section.settings.show_quantity_selector %}
<div class="product-form__item product-form__item--quantity">
<label for="Quantity">{{ 'products.product.quantity' | t }}</label>
<input type="number" id="Quantity" name="quantity" value="1" min="1" class="product-form__input" pattern="[0-9]*">
</div>
{% endif %}
<div class="product-form__item product-form__item--submit">
<button type="submit" name="add" id="AddToCart-{{ section.id }}" {% unless current_variant.available %}disabled="disabled"{% endunless %} class="btn product-form__cart-submit{% if product.options.size == 1 and product.variants[0].title == 'Default Title' %} product-form__cart-submit--small{% endif %}">
<span id="AddToCartText-{{ section.id }}">
{% unless current_variant.available %}
{{ 'products.product.sold_out' | t }}
{% else %}
{{ 'products.product.add_to_cart' | t }}
{% endunless %}
</span>
</button>
</div>
</form>
</div>
<div class="product-single__description rte" itemprop="description">
{{ product.description }}
</div>
{% if section.settings.show_share_buttons %}
{% include 'social-sharing', share_title: product.title, share_permalink: product.url, share_image: product %}
{% endif %}
</div>
</div>
</div>
</div>
{% if collection %}
<div class="text-center return-link-wrapper">
<a href="{{ collection.url }}" class="btn btn--secondary btn--has-icon-before return-link">
{% include 'icon-arrow-left' %}
{{ 'products.product.back_to_collection' | t: title: collection.title }}
</a>
</div>
{% endif %}
{% unless product == empty %}
<script type="application/json" id="ProductJson-{{ section.id }}">
{{ product | json }}
</script>
{% endunless %}
Thanks,
Gavin
I was able to get the respective variant images to show, and selecting from the drop down menu changes the primary variant image.
Two things I noticed:
1. The secondary and tertiary images do not update when switching variants.
2. Reselecting the default variant doesn't update any image at all.
Would anybody be able to clarify?
Hi Gavin and all
Our Symmetry and Showcase themes have this built-in now nativly. So no apps are needed. We added it in the latest update. To learn the steps involved to make it work, you can see our support page on the topic.
We cannot make this work in other 3rd party themes so afraid if you ask the answer will be no.
Display multiple images per product variant
Learn how to expand your operations internationally with Shopify Academy’s learning path...
By Shopify Feb 4, 2025Hey Community, happy February! Looking back to January, we kicked off the year with 8....
By JasonH Feb 3, 2025Expand into selling wholesale with Shopify Academy’s learning path, B2B on Shopify: Lau...
By Shopify Jan 28, 2025