Change "Sale" Badge To "xxx% off" in Refresh Theme

Topic summary

Change the Sale badge to show “xxx% off” in the Refresh theme by editing price.liquid and replacing the translation key (‘products.product.on_sale’) with a computed percentage: (compare_at_price − price) × 100 ÷ compare_at_price.

The initial approach used product.compare_at_price and product.price; it didn’t update correctly for variants.

Fix: use product.selected_or_first_available_variant.compare_at_price and .price so the badge reflects the selected variant’s discount.

Result: the original issue was resolved; multiple users confirmed it works.

For product grids/collection pages, edit card-product.liquid: compute percent from card_product.compare_at_price and card_product.price, round it, and display “Save {{ percent }}%”.

Some users don’t have the on_sale translation key in card-product.liquid, suggesting theme/version differences; apply changes in price.liquid or the equivalent snippet in your version.

Open items: how to implement this in the Dawn theme v9, and ensuring collection page badges show the percentage in all setups.

Key terms: compare_at_price = original/strikethrough price; price = current sale price; translation key labels the sale badge; selected_or_first_available_variant ensures variant-specific pricing. Images/GIFs illustrate behavior; code snippets are central to the solution.

Summarized with AI on January 14. AI used: gpt-5.

I fixed the issue by changing the code from:

 {% comment %} 
{{ 'products.product.on_sale' | t }} 
{% endcomment %} 
{{product.compare_at_price | minus: product.price | times: 100 | divided_by: product.compare_at_price }}% off

to:

{% comment %}
{{ 'products.product.on_sale' | t }} 
{% endcomment %}
{{product.**selected_or_first_available_variant**.compare_at_price | minus: product.**selected_or_first_available_variant**.price | times: 100 | divided_by: product.**selected_or_first_available_variant**.compare_at_price }}% off
1 Like