How to add on product page variant image swatch without app like this in dawn theme

Topic summary

A user seeks to add variant image swatches to product pages in Shopify’s Dawn theme without using an app. Another user provides a code snippet and video tutorial targeting the product-variant-options.liquid file, specifically for color variants.

Implementation challenges:

  • The original poster cannot locate the exact code mentioned in the tutorial within their Dawn 13.0.1 version
  • Code structure differs from the tutorial despite matching theme versions
  • Multiple users report the solution doesn’t work properly in other themes (Spotlight)

Reported issues with Spotlight theme:

  • Swatches display the same image for all variants
  • Visual glitches occur when toggling variant picker visibility
  • Swatches briefly appear correct on page refresh but revert to incorrect display

Current status:
The discussion remains unresolved. The provided code works inconsistently across different themes and versions. Users continue requesting clarification, with one asking if a no-code solution exists. The helper shared their complete product-variant-options.liquid file, but implementation problems persist for multiple participants.

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

How to add on product page variant image swatch without app like this in dawn theme

1 Like

Hello Satyapal,

I’m giving you the code for Add On Product Page Variant Image Swatch, and also giving you a video tutorial

I am giving you a video that will make it easier for you to understand.

Here’s a code:

{% if product.variants[forloop.index0].image != blank and option.name == 'Color' %}
      
    {% else %}
      
    {% endif %}

And here’s a video on how to add this code:https://youtu.be/lacCldZ_iHU

I checked this but getting the issue code that you told to replace is not getting

see code not exact like you told please help me to solve issue

Please check You selected the right file.

showing different please check in updated version 13.0.1

My version is also 13.0.1

but i don’t know why its not matching please copy all code product-variant-options.liquid and send here

{% comment %}
  Renders product variant options

  Accepts:
  - product: {Object} product object.
  - option: {Object} current product_option object.
  - block: {Object} block object.

  Usage:
  {% render 'product-variant-options',
    product: product,
    option: option,
    block: block
  %}
{% endcomment %}
{%- liquid
  assign variants_available_arr = product.variants | map: 'available'
  assign variants_option1_arr = product.variants | map: 'option1'
  assign variants_option2_arr = product.variants | map: 'option2'
  assign variants_option3_arr = product.variants | map: 'option3'

  assign product_form_id = 'product-form-' | append: section.id
-%}

{%- for value in option.values -%}
  {%- liquid
    assign option_disabled = true

    for option1_name in variants_option1_arr
      case option.position
        when 1
          if variants_option1_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
            assign option_disabled = false
          endif
        when 2
          if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
            assign option_disabled = false
          endif
        when 3
          if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == product.selected_or_first_available_variant.option2 and variants_option3_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
            assign option_disabled = false
          endif
      endcase
    endfor
  -%}

  {%- if block.settings.picker_type == 'button' -%}
    
    
  {%- elsif block.settings.picker_type == 'dropdown' -%}
    
  {%- endif -%}
{%- endfor -%}

again install delete current and install new

I am also trying on my liquid file from Spotlight theme but its not working when I just copy and paste the specific section. But when I use your code, it partially works and shows same image for all variants.

Here is my liquid file

{% comment %}
  Renders product variant options

  Accepts:
  - product: {Object} product object.
  - option: {Object} current product_option object.
  - block: {Object} block object.
  - picker_type: {String} type of picker to dispay

  Usage:
  {% render 'product-variant-options',
    product: product,
    option: option,
    block: block
    picker_type: picker_type
  %}
{% endcomment %}
{%- liquid
  assign variants_available_arr = product.variants | map: 'available'
  assign variants_option1_arr = product.variants | map: 'option1'
  assign variants_option2_arr = product.variants | map: 'option2'
  assign variants_option3_arr = product.variants | map: 'option3'

  assign product_form_id = 'product-form-' | append: section.id
-%}

{%- for value in option.values -%}
  {%- liquid
    assign option_disabled = true

    for option1_name in variants_option1_arr
      case option.position
        when 1
          if variants_option1_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
            assign option_disabled = false
          endif
        when 2
          if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
            assign option_disabled = false
          endif
        when 3
          if option1_name == product.selected_or_first_available_variant.option1 and variants_option2_arr[forloop.index0] == product.selected_or_first_available_variant.option2 and variants_option3_arr[forloop.index0] == value and variants_available_arr[forloop.index0]
            assign option_disabled = false
          endif
      endcase
    endfor

    if value.swatch.image
      assign image_url = value.swatch.image | image_url: width: 50
      assign swatch_value = 'url(' | append: image_url | append: ')'
    elsif value.swatch.color
      assign swatch_value = 'rgb(' | append: value.swatch.color.rgb | append: ')'
    else
      assign swatch_value = nil
    endif
  -%}

  {%- capture input_id -%}
    {{ section.id }}-{{ option.position }}-{{ forloop.index0 -}}
  {%- endcapture -%}

  {%- capture label_unavailable %}
    
      {{- 'products.product.variant_sold_out_or_unavailable' | t -}}
    
  {%- endcapture %}

  {%- if picker_type == 'swatch' -%}
    {% assign checked = false %}
    {% if option.selected_value == value %}
      {% assign checked = true %}
    {% endif %}
    {%
      render 'swatch-input',
      id: input_id,
      name: option.name,
      value: value | escape,
      product_form_id: product_form_id,
      checked: checked,
      disabled: option_disabled,
      shape: block.settings.swatch_shape,
      help_text: label_unavailable
    %}
  {%- elsif picker_type == 'button' -%}
    
    
  {%- elsif picker_type == 'dropdown' or picker_type == 'swatch_dropdown' -%}
    
  {%- endif -%}
{%- endfor -%}

Having added your code to my theme Spotlight, I get this

If I set Variantpicker to hide and show again I get

When I go to Product Page I get

If I refresh page I momentarily get the swatches correct but it goes back to last picture.

Any ideas to what I can do?

Is there a way to do it without using code? Thanks for sharing!!!

Doesn’t work in mine. Why ?

https://community.shopify.com/post/2479978