How to dynamically change variant metafield on product page?

Topic summary

Problem: Users need to dynamically update variant metafields on Shopify product pages when customers select different variants, without requiring a full page refresh.

Current Limitation: Multiple users report successfully displaying variant metafields using Liquid code loops, but the information only updates when the page is manually refreshed—creating a poor user experience.

Initial Approach: The original poster used a jQuery script that triggers location.reload() on variant selection, which works but forces an undesirable page refresh.

Recommended Solution: One user (guilhermealbino) provided a JavaScript-based approach:

  • Modify the global.js file to add event listeners that update page sections dynamically
  • Use fetch() to retrieve variant data without full page reload
  • Follow the pattern used for SKU updates (shown in code example)
  • Update the DOM directly using getElementById and innerHTML

Additional Resource: A tutorial link was shared (ecommercepot.com) explaining how to store variant data invisibly on the product page for JavaScript access.

Status: The discussion remains open with users seeking clarification on implementation, particularly for specific themes like Expanse.

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

On the product page, I would like to show the Variant Metafield, I was able to do figure out how to get it in there using this:

{% for variant in product.variants %}
{% if product.selected_or_first_available_variant.id == variant.id %}
<strong>Only {{ variant.metafields.my_fields.quantity_by_color }} PCS are available in {{variant.title}}!</strong>
{% endif %}
{% endfor %}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<script type="text/javascript">
jQuery(document).ready(function($){
$(".no-js-hidden").on("click", function(){
var refreshint = setInterval(function(){
location.reload();
}, 1000);    });   });
</script>

In this example, the person used it to update specific quantities of each variant (in case that is important). I changed it to my metafield and put this in a Custom Liquid block:

{% for variant in product.variants %}
{% if product.selected_or_first_available_variant.id == variant.id %}
{{variant.title}}: {{ variant.metafields.my_fields.shipping_status }}
{% endif %}
{% endfor %}

It works great but the only way to show it when you click on a different variant is to refresh the page which isn’t intuitive - I would like it to change depending on what variant you click.

Thanks!

store is: https://detroit-bikes.myshopify.com/

2 Likes

Did you manage to resolve this?
I’m having a similar situation, but I don’t mind if it is refreshing the page when variant is switched. My problem is that when I change the product quantity, it refreshes the page and sets the quantity’s value to 1 again.

If you solved it, could you share your solution? Thanks.

Exact same issue can someone help please :slightly_smiling_face:

Same problem here. Would love a solution to this. What is the point of having variant metafields if they don’t update when the variant is chosen?

1 Like

Did someone found a solution for this?

In the global.js file you will find the functions that deal with updating parts of the page with eventListener.
In the example I’ll show, let’s pay attention to updating the SKU information, which I put to be shown just below the price on the product page.

Example:

renderProductInfo() {
    fetch(
      `${this.dataset.url}?variant=${this.currentVariant.id}§ion_id=${
        this.dataset.originalSection
          ? this.dataset.originalSection
          : this.dataset.section
      }`
    )
      .then((response) => response.text())
      .then((responseText) => {
        const html = new DOMParser().parseFromString(responseText, "text/html");
        const destination = document.getElementById(
          `price-${this.dataset.section}`
        );
        const source = html.getElementById(
          `price-${
            this.dataset.originalSection
              ? this.dataset.originalSection
              : this.dataset.section
          }`
        );
        if (source && destination) destination.innerHTML = source.innerHTML;

        const price = document.getElementById(`price-${this.dataset.section}`);

        if (price) price.classList.remove("visibility-hidden");

        const sku = document.getElementById(`sku-${this.dataset.section}`);
        if (sku)
          sku.classList.remove("visibility-hidden"), this.updateSku(html);

        this.toggleAddButton(
          !this.currentVariant.available,
          window.variantStrings.soldOut
        );
      });
  }

The function above, calls updateSku() to update its sku dynamically:

updateSku(html) {
    const id = `sku-${this.dataset.section}`;
    const destination = document.getElementById(id);
    const source = html.getElementById(id);

    if (source && destination) destination.innerHTML = source.innerHTML;
  }

Following that logic you’ll can do that kind of update without refreshing the entire page.

Anyone has update on this? I’m using Expanse theme and have the same problem

I manage to show the variant, but the problem the page need to refresh

{% for variant in product.variants %}

{% if variant.metafields.custom.variant_size %}

Dimension:{{ variant.metafields.custom.variant_size }}

{% endif %} {% if variant.metafields.custom.variant_cubage %}

Cubage:{{ variant.metafields.custom.variant_cubage }}

{% endif %}
{%- endfor -%}

I found a great tutorial for how to do this by first placing a record of the variants in the product page (invisibly):

https://ecommercepot.com/shopify-qa/variant-metafield/

1 Like