How can I display dynamic product variants metafields on a product page?

Topic summary

Problem: A user wants to display variant-specific metafields (like “material”) that update dynamically when customers select different product options, similar to how SKU numbers change automatically.

Root Cause: The metafield displays correctly on initial page load but remains static because it’s not connected to the JavaScript variant selection callback function that handles dynamic updates.

Solution Approach:

  1. Capture variant metafield data in product-template.liquid using a Liquid loop that creates a JavaScript object mapping SKU to metafield values:
{% capture 'meta_data' %}
{% for variant in product.variants %}
{{ variant.sku | json }}: {{ variant.metafields.specs.material | json }}
{% endfor %}
{% endcapture %}
  1. Update the selectCallback function in sections.js.liquid to pull and display the metafield based on selected variant:
$('.material span', $product).text(metaData[variant.sku]);
  1. Display the metafield in the product template using the same structure as SKU display.

Common Issues:

  • Variants without metafield data showing previous values (solved by adding null checks in JavaScript)
  • Multiple metafields requiring array formatting
  • Theme-specific implementation differences

Multiple users confirmed this solution works, particularly with Turbo and Debut themes. Some hired developers when unable to implement it themselves.

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

Thanks for sharing your code here, this solution worked great for me. (also using a Turbo theme). One issue i’m trying to sort out is some variants of a product do not have data for a metafield (e.g. I’m using this to display backorder Shipping dates). Do you have any pointers on how i could modify this to not display anything for products that have data in the metafield? Since variant.sku is the filter all variants load the code to display the metafield data.

In my case it is something like this in the product template:

{% capture 'meta_data' %}
  {% for variant in product.variants %}
    {{ variant.sku | json }}: {{ variant.metafields.my_fields.delivery_month | json }}
    {% unless forloop.last %},{% endunless %}
  {% endfor %}
{% endcapture %}

  
                    
{% if variant.sku != blank %}
  

Ships by: {{ variant.sku }}

{% endif %}

and then using this in my sections.js.liquid

$('.backorder span', $product).text(metaData[variant.sku]);