How Can I Add Image Swatches to the Dawn Theme?

Hi everyone, I hope you’re doing well!

I’m using the Dawn theme on Shopify and I would like to add image swatches for product variants (such as colour options), without using any external apps, to keep my store lightweight. I’ve searched for working code and tutorials, but I haven’t found anything clear or helpful. I’m looking for a working code snippet and precise instructions on where exactly to place it within Shopify’s code editor.

Can anyone help me with this or point me in the right direction? I’d really appreciate it!

Hello @vhboy To add image swatches for color variants in the Dawn theme on Shopify (without using apps), you’ll need to customize the main-product.liquid, product-variant-picker.liquid, and global.js files. I’ll walk you through the full process to achieve this cleanly.

What You’ll Achieve:
. Replace the default color variant dropdown or pills with clickable image swatches.

. Keep it lightweight, without apps.

. Show selected state clearly.

Prerequisites:
. You’re using Dawn 9.0.0+ (let me know if your version is older).

. Your product variants have images assigned per color.

Step-by-Step Instructions:

  1. Assign Images to Each Variant
    In your Shopify Admin:

. Go to Products > [Your Product].

. Scroll to Variants, click each one, and upload an image that represents the color.

  1. Edit main-product.liquid
    File path: Sections/main-product.liquid

Look for this block (or similar):

{% render 'product-variant-picker', ... %}

It should already be rendering the picker, so no changes needed here unless it’s missing.

Modify product-variant-picker.liquid
File path: Snippets/product-variant-picker.liquid

Replace the contents only for the color option with image swatches.

Find this loop:

{% for option in product.options_with_values %}

And inside it, look for:

{% if option.name == 'Color' %}

If it doesn’t exist, wrap it yourself like this:

Replace or Insert this inside the loop:

{% if option.name == 'Color' %}
  
{% else %}
  {% render 'product-variant-options', product: product, option: option, product_form_id: product_form_id %}
{% endif %}

This creates image swatches instead of default text/pills for Color.

  1. Add CSS for Swatches
    File path: Assets/base.css or Assets/component-product.css

Scroll to the bottom and add this:

.swatch-container {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin: 1rem 0;
}

.swatch-label {
  position: relative;
  cursor: pointer;
  border: 2px solid transparent;
  padding: 2px;
  border-radius: 4px;
}

.swatch-label input[type="radio"] {
  display: none;
}

.swatch-label .swatch-image {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
  border: 1px solid #ccc;
}

.swatch-label input[type="radio"]:checked + .swatch-image {
  border: 2px solid #000;
}

Done! Test It Out:

  1. Visit a product page with color variants.

  2. Swatches should appear.

  3. Selecting a swatch should change the product image and update the variant selection.

Would you like me to help add hover titles, color names under images, or support for mobile styling

plz let me know

Thank you :blush:

Hello @goldi07 , hope you’re doing well. Thank you for helping me out.

I have a few questions, if you don’t mind clearing them up for me:

I couldn’t find where to place the code in product-variant-picker.liquid. I don’t really understand much about loops and things like that — would it be okay if I send you my full code so you can add it for me? Or perhaps you could tell me exactly which line to insert the code on, if that’s not too much trouble.

{% comment %}
  Renders product variant-picker

  Accepts:
  - product: {Object} product object.
  - block: {Object} passing the block information.
  - product_form_id: {String} Id of the product form to which the variant picker is associated.
  Usage:
  {% render 'product-variant-picker', product: product, block: block, product_form_id: product_form_id %}
{% endcomment %}
{%- unless product.has_only_default_variant -%}
  
{%- endunless -%}

[email removed]

yes, it helps a lot to see your actual product-variant-picker.liquid snippet. I’ll guide you through an exact modification so you can add image swatches for the Color option only, while keeping the other options as they are (dropdowns, buttons, etc.).

Where to Insert the Code
We’ll be modifying just one part inside your existing loop:

{%- for option in product.options_with_values -%}

That loop is already rendering different picker types (swatch, button, dropdown) based on picker_type.

We’ll now intercept that flow for just the Color option and render our custom image swatch block instead.

Step-by-Step Code Insert

  1. Inside your loop, just after this line:

Add this conditional right after the loop starts:

{%- if option.name == 'Color' -%}
  
{%- else -%}
  1. Then, scroll down and find this line (which closes your current picker rendering):
{%- endif -%}
  1. Just after that, add:
{%- endif -%}

This closes your custom if option.name == ‘Color’ logic cleanly.

Your Updated Flow Will Look Like:

{%- for option in product.options_with_values -%}

  {%- if option.name == 'Color' -%}
    
  {%- else -%}
    
    {%- if picker_type == 'swatch' -%}
      ...
    {%- elsif picker_type == 'button' -%}
      ...
    {%- else -%}
      ...
    {%- endif -%}
  {%- endif -%}

{%- endfor -%}

CSS Reminder
In your Assets/base.css (or component-product.css), don’t forget to add:

.swatch-container {
  display: flex;
  gap: 0.5rem;
  flex-wrap: wrap;
  margin-top: 1rem;
}

.swatch-label {
  position: relative;
  cursor: pointer;
  border: 2px solid transparent;
  padding: 2px;
  border-radius: 4px;
}

.swatch-label input[type="radio"] {
  display: none;
}

.swatch-image {
  width: 40px;
  height: 40px;
  object-fit: cover;
  border-radius: 4px;
  border: 1px solid #ccc;
}

.swatch-label input[type="radio"]:checked + .swatch-image {
  border: 2px solid #000;
}

try this and let me if this work i also add a sacreenshot

thank you :blush:

I managed to add it successfully, but when I click on the variant, which is now an image, it doesn’t switch. It’s only possible to view the colour without being able to change it. Do you know how to fix this? I’ll send you my code so you can see how it turned out.

{% comment %}
  Renders product variant-picker

  Accepts:
  - product: {Object} product object.
  - block: {Object} passing the block information.
  - product_form_id: {String} Id of the product form to which the variant picker is associated.
  Usage:
  {% render 'product-variant-picker', product: product, block: block, product_form_id: product_form_id %}
{% endcomment %}
{%- unless product.has_only_default_variant -%}
  
{%- endunless -%}

image.png

hey @vhboy Thanks for sharing your code, — you’re super close! The issue is that while your custom image swatches are rendering perfectly, they’re missing the JavaScript trigger that tells Shopify’s component to update the selected variant when you change the radio button.

Here’s what’s happening:

. The is being rendered correctly.

. But Shopify’s built-in variant-selects.js component listens for change events on the

Hi my friend, how are you? I hope you’re having an excellent day. First of all, I want to thank you for your patience and help—it’s really been a huge support!

I managed to do everything you mentioned, but when I click on the image, it still doesn’t change the variant. I’d like to know what’s missing or what I might have done wrong. I’ll leave my code below.

{% comment %}
  Renders product variant-picker

  Accepts:
  - product: {Object} product object.
  - block: {Object} passing the block information.
  - product_form_id: {String} Id of the product form to which the variant picker is associated.
  Usage:
  {% render 'product-variant-picker', product: product, block: block, product_form_id: product_form_id %}
{% endcomment %}
{%- unless product.has_only_default_variant -%}
  
  
{%- endunless -%}

Hi @vhboy ,

Please refer the below video to see how you can activate color swatch in DAWN theme.

I can’t do what this video suggests with existing products — I’d have to register everything from scratch, and that wasn’t what I was looking for. But I really appreciate your help, mate. @gr_trading

Hi @vhboy :raising_hands:

If your goal is to display color variants as image/color swatches instead of the default dropdown in the Dawn, you can achieve this easily without editing theme code by using Easify Product Options.

I’ve created a similar demo to help you better visualize how it works:

  • This is the result:

  • This is the app setting:

You just need to create a Color option and choose a swatch-style display (e.g., color circles or image swatches). As shown in the demo, each color appears as a clickable swatch, allowing customers to select visually instead of using a dropdown.

When a customer clicks on a color (e.g., Black), the selection updates instantly and is clearly reflected on the interface. This gives you the same result as custom-coded swatches, but without needing to modify Liquid files or figure out where to place code in the theme.

The setup is simple and doesn’t require technical knowledge. It’s a much faster and safer alternative to manual coding while still keeping a clean and lightweight storefront experience.:smiling_face_with_three_hearts:

Hi @vhboy ,
Step 1 - Assign images to each variant

In Shopify Admin → Products → Open product → Go to Variants → Upload an image for each color variant

Step 2 - Edit the variant picker file

Go to Online Store → Themes → Edit code

Open:

Snippets/product-variant-picker.liquid

Find this line:

{% for option in product.options_with_values %}

Replace the block inside that loop with this:

{% for option in product.options_with_values %}

  {% if option.name == 'Color' %}

    <fieldset class="product-form__input product-form__input--swatch">
      <legend>{{ option.name }}</legend>

      {% for value in option.values %}
        {% assign variant_image = null %}

        {% for variant in product.variants %}
          {% if variant.option1 == value %}
            {% assign variant_image = variant.featured_image %}
          {% endif %}
        {% endfor %}

        <input
          type="radio"
          id="{{ option.name }}-{{ value }}"
          name="{{ option.name }}"
          value="{{ value }}"
          form="{{ product_form_id }}"
        >

        <label for="{{ option.name }}-{{ value }}">
          {% if variant_image %}
            <img
              src="{{ variant_image | image_url: width: 60 }}"
              alt="{{ value }}"
              width="40"
              height="40"
            >
          {% else %}
            {{ value }}
          {% endif %}
        </label>

      {% endfor %}

    </fieldset>

  {% else %}

    {% render 'product-variant-options',
      product: product,
      option: option,
      product_form_id: product_form_id
    %}

  {% endif %}

{% endfor %}

Step 3 - Add styling

Assets/base.css

.product-form__input--swatch label {
  border: 1px solid #ddd;
  padding: 2px;
  margin-right: 6px;
  cursor: pointer;
  display: inline-block;
}

.product-form__input--swatch input[type="radio"] {
  display: none;
}

.product-form__input--swatch input[type="radio"]:checked + label {
  border: 2px solid #000;
}