Boost Conversions: How to Dynamically Display Percentage Off on Shopify Sale Badges
Hey store owners! It's always a hot topic in the Shopify community: how do you make your sales stand out? We all know that a simple “Sale” badge is good, but showing a dynamic “-20%” or “-35%” can really catch a customer's eye and drive that conversion. It's a small change with a big impact, and it's something many of you have asked about.
Recently, I saw a great discussion pop up on the forums where a store owner, snnap, was trying to do just this for their Fabric theme (v4.1.1). They mentioned that a lot of the older tutorials seemed out-of-date, which is totally understandable given how fast Shopify themes evolve. It's a common pain point, and the community really came together to hash out some fantastic solutions.
First Things First: Check Your Theme Settings!
Before you even think about diving into code, here's a golden rule I always share: check your theme customization settings! As websensepro wisely pointed out in the thread, many modern Shopify themes, including Fabric (v4.1.1), might have this functionality built right in. This is always the easiest and safest route.
How to Check for Built-in Percentage Badges:
- Go to your Shopify Admin > Online Store > Themes.
- Find your Fabric theme and click the “Customize” button.
- On the far-left sidebar, look for the Gear icon (Theme Settings).
- Browse through sections like Badges, Product Grid, or Products.
- Keep an eye out for dropdown options like “Sale badge format” or “Discount type.” You might be able to simply switch it from “Text” to “Percentage” or “Percent off.”
If you find it, fantastic! You've just saved yourself some coding. If not, don't worry, the community has got your back with some solid code solutions.
When Code is King: Dynamic Percentage Badges with Liquid
If your theme doesn't offer a native setting, or if you need more precise control, custom Liquid code is the way to go. This is where the discussion got really interesting, with ajaycodewiz and Shopatch providing some excellent insights.
The Initial Approach (and its limitations)
Initially, ajaycodewiz provided a solution that worked great for product cards. It involved modifying the blocks/_product-card-gallery.liquid file. The idea was to replace the standard {{ 'content.product_badge_sale' | t }} (which just prints “Sale”) with a Liquid snippet to calculate and display the percentage:
{%- assign badge_pct = product.compare_at_price | minus: product.price | times: 100 | divided_by: product.compare_at_price -%}-{{ badge_pct }}%
Here's what that looked like in action:

And the code snippet for reference:

However, snnap quickly noticed a couple of issues:
- The discount badge wasn't showing on the actual product page.
- For products with multiple variants, the percentage displayed was sometimes incorrect after selecting a different variant.
This is a crucial learning point: where you place your code matters! The initial edit was only affecting product cards, not the main product page, and it was using the default variant's price, not the currently selected one.
The Robust Solution: Product Page & Variant-Specific Discounts
ajaycodewiz then came back with a more robust solution that tackles these common challenges head-on. The trick is to put the badge logic into the price snippet, which is responsible for rendering prices across your store, and to base the percentage calculation on the selected variant.
This ensures the badge:
- Shows up on the product page.
- Updates dynamically when a customer selects a different variant.
- Hides itself if a particular variant isn't on sale.
Step-by-Step Code Implementation:
1. Edit snippets/price.liquid:
Open this file in your theme editor (Admin > Online Store > Themes > Actions > Edit code). After the line that says assign show_compare_price = ..., add the following code:
assign show_discount_badge = show_discount_badge | default: false
assign discount_pct = 0
if show_compare_price
assign discount_pct = selected_variant.compare_at_price | minus: selected_variant.price | times: 100 | divided_by: selected_variant.compare_at_price
endif
Then, as the very first thing inside the Note on Styling: The 2. Edit This file is likely calling the This effectively “turns on” the badge for that specific render call, ensuring it appears where you want it. Liquid performs integer math by default. So, Here's what This community discussion really highlights a few critical points for any Shopify store owner looking to customize their theme: Implementing dynamic percentage badges can significantly improve how customers perceive your sales, making discounts clear and compelling right from the product page. It's a fantastic way to boost engagement and conversions. If you're looking to start your own Shopify store and want to implement these kinds of dynamic features, you can sign up for Shopify here and dive right in. Happy selling!{%- if show_discount_badge and show_compare_price -%}
-{{ discount_pct }}%
{%- endif -%}
style attribute here is inline for demonstration. For a cleaner approach, you'd typically add these styles to your theme's CSS file (e.g., theme.scss.liquid or a custom CSS file) and use a class instead of inline styles.blocks/price.liquid:price snippet. You'll need to tell it to show the discount badge. Find the {% render 'price' ... %} call and add one line to its parameters: show_discount_badge: true
Understanding the Percentage Math
Shopatch offered a great breakdown of the Liquid math. The key part is: product.compare_at_price | minus: product.price | times: 100 | divided_by: product.compare_at_price.
minus: product.price: Calculates the saving amount.times: 100: Multiplies the saving by 100.divided_by: product.compare_at_price: Divides by the original price to get the percentage.times: 100 | divided_by will give you a clean integer percentage (it essentially “floors” the number). If you prefer rounding, Shopatch suggested | times: 100.0 | divided_by: product.compare_at_price | round to force float division before rounding.snnap shared after applying some of the fixes, showing the badge:
Final Thoughts and Best Practices
price.liquid or blocks like _product-card-gallery.liquid are used is crucial for effective changes.selected_variant to show accurate information.