Unlock Dynamic Sale Badges on Shopify's Horizon Theme: A Community-Backed Guide
Hey fellow store owners!
One of the most effective ways to grab a customer's attention and highlight value on your product pages is a clear, eye-catching sale badge. But if you're running the sleek new Horizon theme on Shopify, you might have noticed it's not always straightforward to get those badges working dynamically, especially when you have products with multiple variants, each with its own pricing. That's exactly what our friend SurfBark ran into in a recent community discussion, asking for help to display a "SAVE $5" or "15% OFF" badge that updates with variant selection.
This challenge is super common. You want a badge that not only looks great but also intelligently reflects the correct discount, whether it's a percentage or a dollar amount, as customers switch between sizes or styles. And crucially, it needs to be a compact, modern "pill" badge, not something that stretches awkwardly across your layout.
The community really came through with some fantastic, detailed solutions that I want to break down for you. The key, as several experts like v.marychenka and Shopplaza's Titan pointed out, lies in modifying the snippets/price.liquid file. This is where the magic happens for handling price displays, and it's the perfect spot to inject our dynamic discount logic.
Why Dynamic Badges Are a Must-Have (and a Bit Tricky)
Imagine a customer browsing your store. They see a product, click on it, and then select a different size or color. If your sale badge is static, showing a discount based on the default variant, it instantly becomes misleading if the new variant has a different price or no discount at all. This can lead to frustration and lost sales. The Horizon theme, with its reactive custom element, is designed to update pricing dynamically, so our badge needs to play along.
Here's a look at what SurfBark was aiming for, and what we're going to achieve:


Your Step-by-Step Guide to Dynamic Sale Badges on Horizon
Before you dive into any code, always remember the golden rule of Shopify customization: duplicate your theme! Go to "Online Store" > "Themes," find your Horizon theme, click "Actions," and select "Duplicate." This creates a safe backup in case anything goes awry. You can work on the duplicate and publish it once you're happy.
1. Add the Savings Calculation
We need to calculate the savings amount and percentage right where the prices are being processed. Open your theme editor (Online Store > Themes > Actions > Edit code), and navigate to snippets/price.liquid.
Look for the {%- liquid ... -%} block at the very top of the file. You'll want to insert the following code right after the existing show_compare_price logic. This ensures our calculations happen before prices are formatted into money strings.
assign show_compare_price = false
if compare_at_price > price
assign show_compare_price = true
endif
assign saved_amount = 0
assign saved_percent = 0
if show_compare_price
assign saved_amount = compare_at_price | minus: price
assign saved_percent = saved_amount | times: 100 | divided_by: compare_at_price
endif
2. Display the Badge
Now that we have our saved_percent, let's display it! Stay in snippets/price.liquid. You'll find a section for "Standard pricing display." We need to place our badge HTML inside the show_compare_price block, specifically after the show_sale_price_first if/else statements. This is crucial because the element re-renders this entire block on variant changes, keeping your badge perfectly in sync.
Here's the snippet to add. Note the is_product_card == false check from v.marychenka's solution, which prevents the badge from showing up on collection cards where the theme might already have its own sale indicator:
{% comment %} Standard pricing display: render only the active branch (regular or sale) {% endcomment %}
{% if show_compare_price %}
{% if show_sale_price_first %}
{{ 'content.price_sale' | t }}
{{ price | default: ' ' }}
{{ 'content.price_regular' | t }}
{{- compare_at_price -}}
{% else %}
{{ 'content.price_regular' | t }}
{{- compare_at_price -}}
{{ 'content.price_sale' | t }}
{{ price | default: ' ' }}
{% endif %}
{%- if is_product_card == false -%}
Save {{ saved_percent }}%
{%- endif -%}
{% else %}
{{ price | default: ' ' }}
{% endif %}
You can adjust the text inside the to say "{{ saved_amount | money }} OFF" or combine them like "Save {{ saved_amount | money }} ({{ saved_percent }}% off)" if you prefer, as v.marychenka suggested. Just make sure to use the correct Liquid filters (money for dollar amounts, round if you want to ensure percentages are whole numbers).
3. Style It Up: The Compact Pill Badge
SurfBark specifically asked for a compact pill badge, and Titan from Shopplaza delivered some excellent CSS for that! To apply these styles, open assets/base.css or assets/theme.css (depending on your theme's structure, base.css is common for Horizon). Add this code to the very bottom of the file.
[ref="priceContainer"] {
display: flex;
align-items: center;
flex-wrap: wrap;
gap: 8px;
}
[ref="priceContainer"] .price-item__group.price {
color: #e8590c;
font-weight: 700;
font-size: 18px;
}
[ref="priceContainer"] .price-item--regular.compare-at-price {
color: #6b6b6b;
text-decoration: line-through;
font-weight: 400;
font-size: 15px;
}
.badge--savings {
display: inline-flex;
align-items: center;
justify-content: center;
background-color: #e8590c;
color: #ffffff;
font-weight: 700;
font-size: 13px;
padding: 6px 14px;
border-radius: 999px;
white-space: nowrap;
}
This CSS not only styles your new .badge--savings class into a neat pill shape but also tidies up the price display around it, ensuring everything aligns nicely. You can easily tweak the background-color, color, font-size, and padding to match your brand's aesthetic. The border-radius: 999px; is what gives it that perfect pill shape.
Here's what the final result should look like, courtesy of Shopplaza's example:

It's a fantastic example of how a little Liquid and CSS can make a big difference in user experience and conversion rates. The beauty of this solution is that because the Horizon theme's component is reactive, your badge will automatically update whenever a customer selects a different variant, without needing any complex JavaScript. This kind of thoughtful detail really elevates your store.
Big thanks to SurfBark for asking such a pertinent question and to v.marychenka and Shopplaza for providing such comprehensive and actionable solutions. It just goes to show how invaluable the Shopify community is when you're looking to push the boundaries of your store's design and functionality. Don't hesitate to experiment with the colors and sizing to perfectly integrate this badge into your unique brand!