How to display multiple images per product variant in the Debut theme?

Topic summary

Users are seeking methods to display multiple images per product variant in Shopify’s Debut theme, where each variant shows only its relevant images rather than all product photos.

Core Challenge:

  • Default Debut theme shows all product images regardless of selected variant
  • Goal is to filter images by variant selection (often using matching alt tags)
  • Existing tutorials appear outdated or incompatible with newer Debut versions (V16+)

Reported Issues:

  • Primary variant image updates on selection, but secondary/tertiary images don’t refresh
  • Reselecting the default variant fails to update images
  • Code referenced in older tutorials no longer exists in updated Debut versions due to video/3D model support changes

Proposed Solutions:

  • Several tutorial links shared (some potentially outdated)
  • Multiple paid apps mentioned: Easy Variant Images, Rubik Variant Images
  • Premium themes (Symmetry, Showcase) offer native support
  • Video tutorials provided, though effectiveness with current Debut version unclear

Current Status:
Discussion remains open with no confirmed working solution for recent Debut versions. Users express frustration that this functionality isn’t native to Shopify and requires custom code modifications or paid apps.

Summarized with AI on November 4. AI used: claude-sonnet-4-5-20250929.

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

1 Like

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.

1 Like

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’ %}> > > > {% include ‘pagefly’ %}> >

product-template.liquid

<div class="product-template__container page-width" itemscope itemtype="[http://schema.org/Product](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](http://schema.org/Offer)">
          <meta itemprop="priceCurrency" content="{{ shop.currency }}">

          <link itemprop="availability" href="[http://schema.org/](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?

1 Like

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…

2 Likes

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…

1 Like

Ah ok, sorry. I hadn’t tried it yet.

I’ll keep looking and post here if I find a solution.

1 Like

Have you find any solution for these?

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.

Variant Image Grouping Guide

We cannot make this work in other 3rd party themes so afraid if you ask the answer will be no.

yay! let’s all pay for something that should come default in shopify!

Display multiple images per product variant

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.