Can't display selected variant price when ex.VAT toggled

Topic summary

A developer is struggling to display dynamically calculated ex-VAT prices for product variants on a Shopify B2B site using the Empire theme.

The Problem:

  • A toggle switches between inc-VAT and ex-VAT prices (calculated by dividing by 1.2)
  • Works correctly for products without variants
  • For products with variants: the inc-VAT price updates correctly when variants change, but the ex-VAT price remains stuck showing only the original variant’s calculated price

Attempted Solutions:

  • Modified the product-price.liquid snippet to include both price spans
  • Added JavaScript to listen for variant changes and recalculate ex-VAT pricing using updateExVatPrice() function
  • Updated variantFields object to track price elements

Current Status:

  • The toggle functionality works
  • The data-price attribute correctly updates for inc-VAT prices
  • The ex-VAT calculation fails to respond to variant selection changes
  • Developer suspects either missing element updates or Liquid template limitations

Code snippets provided show the product-price snippet, toggle controls, and JavaScript event listener implementation.

One respondent suggested a third-party app (Taxify) as an alternative solution without code changes.

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

Hello,

I have a B2B site and I display product priced ex.Vat as well as with VAT so the customer can view both by toggling between classes.

When the page loads the displays

when toggled the second price which is initially hidden is then displayed and hides the first price.

Below I have added this code to the product-price snippet within the empire theme.

It works for a product without variants.

However when a product has variants the price will display correctly for whatever variant it selected, but the toggled ex.Vat price only shows the original variants price for all the variants no matter which one is selected.

Does anyone know how I can write within the to select the current variant. Every combination I try to write within the {{ price | divided_by : 1.2 | money }} comes back as either 0.00 or still displays the original variants price only. Its seems I can’t apply a calculation to a variant price.

  <div class="price__current {% if emphasize_price %}price__current--emphasize{% endif %} {% if on_sale %}price__current--on-sale{% endif %}" data-price-container>
    {%- capture price_html -%}
  
        <div class="price-container label">
    <!-- Display the first price -->
    <span class="inc-vat-price" data-price>{{ price | money }} {{ product.metafields.sold-by-the.volume }}</span>
    <!-- Display the second price, initially hidden -->
    <span class="ex-vat-price"><span class="smaller">Ex.VAT</span>{{ price | divided_by : 1.2 | money }} {{ product.metafields.sold-by-the.volume }}</span>
  </div>
    

    {%- endcapture -%}

Within the Js file is the data-price details put can’t see anyway this will help

 this.variantFields = {
$priceContainer: this.$details.find('[data-price-container]'),
$priceMoney: this.$details.find('[data-price-container] [data-price]'),
$compareAtPrice: this.$details.find('[data-price-compare-container]'),
$compareAtPriceMoney: this.$details.find('[data-price-compare-container] [data-price-compare]'),
$badge: this.$details.find('[data-badge-sales]'),
$badgeRange: this.$details.find('[data-badge-sales-range]'),
$badgeSingle: this.$details.find('[data-badge-sales-single]'),
$sku: this.$details.find('[data-product-sku]'),
stockLevels: this.$details[0].querySelectorAll('[data-stock-level]'),
unitPrice: this.$details[0].querySelector('[data-unit-price]'),
totalQuantity: this.$details[0].querySelector('[data-total-quantity]'),
unitPriceAmount: this.$details[0].querySelector('[data-unit-price-amount]'),
unitPriceMeasure: this.$details[0].querySelector('[data-unit-price-measure]'),
taxLine: this.$details[0].querySelector('[data-tax-line]'),
hiddenComparePrice: this.$details[0].querySelector('[data-compare-price-hidden]'),
hiddenCurrentPrice: this.$details[0].querySelector('[data-current-price-hidden]'),
hiddenComparePriceRange: this.$details[0].querySelector('[data-compare-price-range-hidden]'),
hiddenCurrentPriceRange: this.$details[0].querySelector('[data-current-price-range-hidden]')
};

Thanks

1 Like

This looks good thank you but I’m a little unsure how to update the product-price snippet so it calls this command?


    
    {{ price | money }} {{ product.metafields.sold-by-the.volume }}
    
    Ex.VAT{{ price | divided_by : 1.2 | money }} {{ product.metafields.sold-by-the.volume }}

  

also here is the script I already use to use for the toggle to switch between one price and the other in case this effects your code.


It all makes sense but for some reason its still not working as intended.

I’m sure I’m missing something simple.

Here is all the updated codes based on your instructions.

The product-price.liquid snippet which displays pricing on product pages.

    {%- capture price_html -%}
   
        

    
    {{ price | money }} {{ product.metafields.sold-by-the.volume }}
    
    Ex.VAT{{ price | divided_by : 1.2 | money }} {{ product.metafields.sold-by-the.volume }}

 

The product.liquid snippet with toggle controls. Separate from the product-form snippet.

{% if customer.b2b? %}

           
    
     Retail {{ product.metafields.sqm.price }} Inc.VAT
     
  

     Vat       
     

in the original answer you included script to be added to the js file so here it is as currently added

this.variantFields = {
      $priceContainer: this.$details.find('[data-price-container]'),
      $priceMoney: this.$details.find('[data-price-container] [data-price]'),
      $compareAtPrice: this.$details.find('[data-price-compare-container]'),
      $compareAtPriceMoney: this.$details.find('[data-price-compare-container] [data-price-compare]'),
      $badge: this.$details.find('[data-badge-sales]'),
      $badgeRange: this.$details.find('[data-badge-sales-range]'),
      $badgeSingle: this.$details.find('[data-badge-sales-single]'),
      $sku: this.$details.find('[data-product-sku]'),
      stockLevels: this.$details[0].querySelectorAll('[data-stock-level]'),
      unitPrice: this.$details[0].querySelector('[data-unit-price]'),
      totalQuantity: this.$details[0].querySelector('[data-total-quantity]'),
      unitPriceAmount: this.$details[0].querySelector('[data-unit-price-amount]'),
      unitPriceMeasure: this.$details[0].querySelector('[data-unit-price-measure]'),
      taxLine: this.$details[0].querySelector('[data-tax-line]'),
      hiddenComparePrice: this.$details[0].querySelector('[data-compare-price-hidden]'),
      hiddenCurrentPrice: this.$details[0].querySelector('[data-current-price-hidden]'),
      hiddenComparePriceRange: this.$details[0].querySelector('[data-compare-price-range-hidden]'),
      hiddenCurrentPriceRange: this.$details[0].querySelector('[data-current-price-range-hidden]')
    };

    // Function to update ex.Vat price
function updateExVatPrice() {
    var currentPrice = parseFloat(this.variantFields.$priceMoney.attr('data-price'));
    var exVatPrice = currentPrice / 1.2;
    this.variantFields.$priceContainer.find('.ex-vat-price').text('Ex.VAT ' + exVatPrice.toFixed(2));
}

// Listen for changes in variant selection
document.addEventListener('change', function(event) {
    // Call the function to update ex.Vat price
    updateExVatPrice();
});

so the toggle currently works but the original price is the only price being displayed for the Ex Vat amount no matter which variant is being selected. The full retail price or include Vat is still displaying all prices for any variant as it has the data-price applied to the span

Have I forgotten to update an element or missing something? Or is it something that can’t be done based on current liquid commands?

Thanks

If you are still looking for showing prices including and excluding VAT without making any theme code changes, we’ve just launched a new app called Taxify which does just that :slight_smile: