Select Variant By Clicking Their Image

Topic summary

A user asks how to enable variant selection by clicking product images on the Warehouse theme, rather than using dropdown menus. They want customers to click a color option image (e.g., blue frog) to automatically select that variant.

Proposed Solution:

  • One responder provides JavaScript code to add to theme.js or global.js files
  • The code creates variant-image mappings and adds click listeners to product thumbnails
  • Implementation involves editing theme code files in the Online Store editor

Current Status:

  • The provided code snippet did not work for the original poster
  • Multiple community members have offered to review the specific store setup privately
  • Another responder notes this is an “advanced theme customization” called “linked variant images” with implementation varying by theme
  • A reference to archived Shopify documentation for vintage themes was shared

Next Steps:
The discussion remains open with offers for direct assistance via DM/email to troubleshoot the specific store configuration.

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

Hey everyone,

Is it possible to Select a Variant By Clicking Their Image on the Ware house Th?

Essentially I want to leave all of the images on the main section of the product. Showing all the different colour options, but be able to have the variant change when someone clicks the images vs them having to click on the tab that has the variant name. So if someone clicks a photo of the blue frog, the product variant selected will change to the blue frog.

Thanks!

Hey! @PCS41 ,

Go to Online Store, then Theme, and select Edit Code.
Search for theme.js /global.js/theme.js.liqui file add the provided code at the end of the file.

const selectVariantByClickingImage = {
  // Create variant images from productJson object
  _createVariantImage: function (product) {
    const variantImageObject = {};
    product.variants.forEach((variant) => {
      if (
        typeof variant.featured_image !== 'undefined' &&
        variant.featured_image !== null
      ) {
        const variantImage = variant.featured_image.src
          .split('?')[0]
          .replace(/http(s)?:/, '');
        variantImageObject[variantImage] =
          variantImageObject[variantImage] || {};
        product.options.forEach((option, index) => {
          const optionValue = variant.options[index];
          const optionKey = `option-${index}`;
          if (
            typeof variantImageObject[variantImage][optionKey] === 'undefined'
          ) {
            variantImageObject[variantImage][optionKey] = optionValue;
          } else {
            const oldValue = variantImageObject[variantImage][optionKey];
            if (oldValue !== null && oldValue !== optionValue) {
              variantImageObject[variantImage][optionKey] = null;
            }
          }
        });
      }
    });
    return variantImageObject;
  },
  _updateVariant: function (event, id, product, variantImages) {
    const arrImage = event.target.src
      .split('?')[0]
      .replace(/http(s)?:/, '')
      .split('.');
    const strExtention = arrImage.pop();
    const strRemaining = arrImage.pop().replace(/_[a-zA-Z0-9@]+$/, '');
    const strNewImage = `${arrImage.join('.')}.${strRemaining}.${strExtention}`;
    if (typeof variantImages[strNewImage] !== 'undefined') {
      product.variants.forEach((option, index) => {
        const optionValue = variantImages[strNewImage][`option-${index}`];
        if (optionValue !== null && optionValue !== undefined) {
          const selects = document.querySelectorAll('#'+ id + ' [class*=single-option-selector]');
          const options = selects[index].options;
          for (let option, n = 0; (option = options[n]); n += 1) {
            if (option.value === optionValue) {
              selects[index].selectedIndex = n;
              selects[index].dispatchEvent(new Event('change'));
              break;
            }
          }
        }
      });
    }
  },
  _selectVariant: function() {
    const productJson = document.querySelectorAll('[id^=ProductJson-');
    if (productJson.length > 0) {
      productJson.forEach((product) => {
        const sectionId = product.id.replace("ProductJson-", "shopify-section-");
        const thumbnails = document.querySelectorAll('#'+ sectionId + ' img[src*="/cdn/"]');
        if (thumbnails.length > 1) {
          const productObject = JSON.parse(product.innerHTML);
          const variantImages = this._createVariantImage(productObject);
          // need to check variants > 1
          if (productObject.variants.length > 1) {
            thumbnails.forEach((thumbnail) => {
              thumbnail.addEventListener('click', (e) =>
                this._updateVariant(e, sectionId, productObject, variantImages),
              );
            });
          }
        }
      });
    }
  },
};
if (document.readyState !== 'loading') {
  selectVariantByClickingImage._selectVariant();
} else {
  document.addEventListener(
    'DOMContentLoaded',
    selectVariantByClickingImage._selectVariant(),
  );
}

If this code doesn’t work for you, feel free to DM me with your store URL and the community link.

Hi @PCS41 :waving_hand: this is an advanced theme customization commonly referred to as linked variant images.

To DIY search online but the implementation varies wildly by theme and other considerations.

For vintage themes there used to be a tut on docs but it’s missing now

https://web.archive.org/web/20241212144049/https://help.shopify.com/en/manual/online-store/themes/themes-by-shopify/vintage-themes/customizing-vintage-themes/select-variants-click

If you need this customization then contact me for services.
Contact info in forum signature below :down_arrow: :down_arrow: :down_arrow:.
ALWAYS please provide context, examples: store url, theme name, post url(s) , or any further detail in ALL correspondence.

Unfortunately it didn’t work when inputting that code into my theme.js file

Could you kindly share your store URL and password (if it’s password-protected) so I can review it and provide you with an update?

I don’t seem to have the availability to send a DM, is an email ok?

Yes, ok

Hi @PCS41 ,

Please send the website link, I will check it for you