Adding price per unit to the product variant picker - pill

Topic summary

Goal: add price-per-unit to each product variant “pill” for 250g, 500g, and 1kg options.

Current behavior: the price-per-unit of the currently selected variant can be shown on all pills, but the correct price-per-unit for unselected variants does not appear on their respective pills.

Code context: product-variant-options.liquid loops through option.values and renders inputs for swatch, button, and dropdown picker types. It uses value.selected and availability, and includes data attributes (e.g., data-option-value-id, data-product-url). The user cannot access or display each unselected variant’s price-per-unit within the loop.

Attachments: a screenshot and a code snippet are central to understanding the issue.

Request: a fix or method to retrieve and display the per-unit price for each variant value (not only the selected one) in the pill layout.

Status: no solution provided yet; discussion remains open with the key question unresolved.

Summarized with AI on December 10. AI used: gpt-5.

I sell food items in 250g, 500g, and 1kg variants. I’d like to add the price per unit to the pill layout of the product varient picker - see image attached

This is my product-variant-options.liquid, where I can easily add the price per unit of the currently selected variant to all pills, but for the life if me, I can’t get the price per unit of the not currently selected varants to show on their respective pills

Does anyone have a fix for this?

{% comment %}

Renders product variant options

Accepts:

  • product: {Object} product object.

  • option: {Object} current product_option object.

  • block: {Object} block object.

  • picker_type: {String} type of picker to dispay

Usage:

{% render ‘product-variant-options’,

product: product,

option: option,

block: block

picker_type: picker_type

%}

{% endcomment %}

{%- liquid

assign product_form_id = ‘product-form-’ | append: section.id

-%}

{%- for value in option.values -%}

{%- liquid

assign swatch_focal_point = null

if value.swatch.image

assign image_url = value.swatch.image | image_url: width: 50

assign swatch_value = ‘url(’ | append: image_url | append: ‘)’

assign swatch_focal_point = value.swatch.image.presentation.focal_point

elsif value.swatch.color

assign swatch_value = ‘rgb(’ | append: value.swatch.color.rgb | append: ‘)’

else

assign swatch_value = null

endif

assign option_disabled = true

if value.available

assign option_disabled = false

endif

-%}

{%- capture input_id -%}

{{ section.id }}-{{ option.position }}-{{ forloop.index0 -}}

{%- endcapture -%}

{%- capture input_name -%}

{{ option.name }}-{{ option.position }}

{%- endcapture -%}

{%- capture input_dataset -%}

data-product-url="{{ value.product_url }}"

data-option-value-id="{{ value.id }}"

{%- endcapture -%}

{%- capture label_unavailable -%}

{{- ‘products.product.variant_sold_out_or_unavailable’ | t -}}

{%- endcapture -%}

{%- if picker_type == ‘swatch’ -%}

{%- capture help_text -%}

{{ value | escape }}

{{ label_unavailable }}

{%- endcapture -%}

{%

render ‘swatch-input’,

id: input_id,

name: input_name,

value: value | escape,

swatch: value.swatch,

product_form_id: product_form_id,

checked: value.selected,

visually_disabled: option_disabled,

shape: block.settings.swatch_shape,

help_text: help_text,

additional_props: input_dataset

%}

{%- elsif picker_type == ‘button’ -%}

<input

type=“radio”

id=“{{ input_id }}”

name=“{{ input_name | escape }}”

value=“{{ value | escape }}”

form=“{{ product_form_id }}”

{% if value.selected %}

checked

{% endif %}

{% if option_disabled %}

class=“disabled”

{% endif %}

{{ input_dataset }}

>

{{ value -}}

{{ label_unavailable }}

{%- elsif picker_type == ‘dropdown’ or picker_type == ‘swatch_dropdown’ -%}

<option

id=“{{ input_id }}”

value=“{{ value | escape }}”

{% if value.selected %}

selected=“selected”

{% endif %}

{% if swatch_value and picker_type == ‘swatch_dropdown’ %}

data-option-swatch-value=“{{ swatch_value }}”

{% if swatch_focal_point %}

data-option-swatch-focal-point=“{{ swatch_focal_point }}”

{% endif %}

{% endif %}

{{ input_dataset }}

>

{% if option_disabled -%}

{{- ‘products.product.value_unavailable’ | t: option_value: value -}}

{%- else -%}

{{- value -}}

{%- endif %}

{%- endif -%}

{%- endfor -%}

Hi @torresa,

I see what you are trying to do. This is a great UX improvement to show the value upfront without clicking.

The issue in your screenshot is that by nesting for variant in product.variants inside the option loop without filters, you are iterating through every single variant for every single button, which can cause performance issues or incorrect price matching.

For products with only ONE option (e.g., strictly “Weight” or “Size”), here is the cleanest Liquid code to achieve this:

You need to find the specific variant that matches the current value being rendered in the loop.

<label>
  {{ value }}

  {%- comment -%} Find the variant where 'option1' matches the current value {%- endcomment -%}
  {%- assign matched_variant = product.variants | where: "option1", value | first -%}
  
  {%- if matched_variant -%}
    <span class="pill-price">
       - {{ matched_variant.price | money }}
    </span>
    
    {%- comment -%} Optional: To display the actual Unit Price (e.g. $0.10/g) {%- endcomment -%}
    {%- if matched_variant.unit_price_measurement -%}
      <span class="unit-price">
        ({{ matched_variant.unit_price | money }} / {{ matched_variant.unit_price_measurement.reference_unit }})
      </span>
    {%- endif -%}
  {%- endif -%}
</label>

Important Note on Logic: Should your products have multiple options (e.g., Color AND Size), this Liquid-only approach becomes risky because “Red” could have multiple prices depending on the size. In that case, you would typically need JavaScript to listen to the state change.

But for single-option products (like bulk items), the code above is the most efficient method.

Hope this helps!

@thomshaw - it will need code editing as mentioned by @luisforero , are you familiar with the liquid coding? if no then I can do it for you.

When pasting code, use the </> button, otherwise forum engine eats some of it.

This is great and works exceptionally well - how would I change the styling on the current variant to display the price per unit in the same colour as the weight and value text?

Any thoughts on how to set the selected variants price per unit text colour to #faf7ed @luisforero