Variant selector reverts to first option on all standard products (Dawn-based theme)

On all product pages using standard Shopify options (Size, Scent, etc.), selecting any variant causes the page to revert back to the first option after a brief delay. Products using linked metafields (lip balm) work fine.

Files already modified:

  • assets/global.jssetTimeout added to connectedCallback in VariantSelects; null check in updateSelectionMetadata
  • assets/product-info.jsthis.updateOptionValues(html) commented out in handleUpdateProductInfo
  • snippets/product-variant-options.liquid — explicit data-option-value-id on radio inputs; whitespace removed from input_id and input_name captures

Suspicion: selectedOptionValues getter may be returning empty/wrong IDs, causing the server fetch to return the wrong variant.

The brief delay before the selector snaps back makes selectedOptionValues less likely to be the first cause. A wrong variant fetch normally changes the selection during the fetch; a correct selection that resets a moment later more often means a second render or event is writing the old option state back.

I would stop adding patches and isolate this in an unpublished duplicate:

  1. Preview the same standard product in a clean, unmodified copy of the current Dawn release.
  2. If it works there, restore your three changed files one at a time in the duplicate until the reset returns.
  3. If it also fails in clean Dawn, temporarily remove app blocks/scripts from that product template and retest.

Could you share the current theme version and whether that same product reverts in a clean unpublished Dawn copy? That one result separates a theme-code regression from product/app data without risking more changes to the live theme.

Standard Dawn and Horizon family themes are usually good to go out of the box, so you usually don’t need to do any modifications to the theme files, let alone all those.

So unless you are trying to do something out of the ordinary, I would suggest getting a new fresh theme, or reverting. There should be nothing wrong with the standard variant selector as it ships.

That said, there are situations where customizations are needed, such as displaying “featured image” rather than the assignment made in the product editor.

Such as it is, there is no information here that can be researched. Without specifics, like theme name, store url, screenshots, and exact issue, no one can give you any answers. I will say it is wild to see you’ve modified all those files and still have a problem. Maybe the problem is the modification? Sometimes the answer is a simple theme setting.

Hi @HollowHickory

Dawn re-fetches the section on every variant change and swaps in the response, so the snap back is that HTML coming back with the first option selected. Most likely your edit to product-variant-options.liquid, since stripping whitespace from the input_id and input_name captures makes the JS send an option_values param that no longer matches the clicked option, so the server renders the default. That’s also why the lip balm works, linked metafields go through the swatch path.

Check it in DevTools, Network: compare option_values in the section request URL to the data-option-value-id on the radio you clicked. Revert all three files to stock first though. Happy to trace it if you want.

Best,
Moeed

I was able to fix the issue by doing the following:

The fix: Wrap the entire script initialization so it only runs when the multi-flavor picker elements actually exist on the page. Here’s what to change in buy-buttons.liquid:

Find this line near the bottom of the script:

if (document.readyState === 'loading') {
  document.addEventListener('DOMContentLoaded', initPicker);
} else {
  initPicker();
}

Replace it with:

// Only run on the lip balm product page
var isLipBalmPage = window.location.pathname.indexOf('/products/lip-balm') !== -1;

if (isLipBalmPage) {
  if (document.readyState === 'loading') {
    document.addEventListener('DOMContentLoaded', initPicker);
  } else {
    initPicker();
  }
}

This is very precise — /products/lip-balm will only match your lip balm page and nothing else in your store. Save it and test a honey jar or other product page — the polling loop will be completely dead on every other page. :honey_pot:

now mark it as solution to help others