Free shipping bars are one of the highest-ROI additions you can make to a Shopify store. They increase average order value by nudging customers to add more to their cart — and the best part is, you don't need a $10/month app to get one.
In this tutorial, you'll add a fully responsive, animated progress bar that shows customers exactly how close they are to free shipping. It updates dynamically with the cart and works on every OS 2.0 theme.
What You'll Build
- An animated progress bar that fills as the cart value increases
- Dynamic messaging: "You're $X away from free shipping!"
- A celebration state when the threshold is reached
- Fully customisable colours, threshold, and sizing via CSS variables
- Zero external dependencies — pure Liquid and CSS
The Code
Here's the complete snippet. Copy it, paste it into a new file in your Shopify theme, and you're done.
{% comment %}
Plynthr — Free Shipping Progress Bar
https://plynthr.com/snippets/free-shipping-bar/
INSTALL:
1. Create snippets/plynthr-free-shipping-bar.liquid
2. Paste this code
3. Add {%- render 'plynthr-free-shipping-bar' -%} in your cart drawer,
cart page, or announcement area
CUSTOMIZE:
- Set your free shipping threshold below
- --pfs-bar-color for the progress bar color
{% endcomment %}
{%- assign free_shipping_threshold = 100 -%}
{%- assign cart_total = cart.total_price | divided_by: 100.0 -%}
{%- assign remaining = free_shipping_threshold | minus: cart_total -%}
{%- assign progress = cart_total | divided_by: free_shipping_threshold | times: 100 | at_most: 100 -%}
<style>
:root {
--pfs-bg: #f5f5f5;
--pfs-bar-color: #10b981;
--pfs-bar-complete: #059669;
--pfs-text-color: #333;
--pfs-radius: 20px;
--pfs-height: 8px;
}
.plynthr-shipping-bar {
padding: 12px 16px;
text-align: center;
}
.plynthr-shipping-bar__text {
font-size: 13px;
color: var(--pfs-text-color);
margin-bottom: 8px;
font-weight: 500;
}
.plynthr-shipping-bar__text strong {
font-weight: 700;
}
.plynthr-shipping-bar__track {
width: 100%;
height: var(--pfs-height);
background: var(--pfs-bg);
border-radius: var(--pfs-radius);
overflow: hidden;
}
.plynthr-shipping-bar__fill {
height: 100%;
border-radius: var(--pfs-radius);
background: var(--pfs-bar-color);
transition: width 0.5s ease;
width: {{ progress }}%;
}
.plynthr-shipping-bar__fill.is-complete {
background: var(--pfs-bar-complete);
}
</style>
<div class="plynthr-shipping-bar">
{%- if remaining <= 0 -%}
<p class="plynthr-shipping-bar__text">🎉 You qualify for <strong>free shipping!</strong></p>
<div class="plynthr-shipping-bar__track">
<div class="plynthr-shipping-bar__fill is-complete" style="width: 100%"></div>
</div>
{%- elsif cart.item_count == 0 -%}
<p class="plynthr-shipping-bar__text">Free shipping on orders over <strong>{{ free_shipping_threshold | money }}</strong></p>
<div class="plynthr-shipping-bar__track">
<div class="plynthr-shipping-bar__fill" style="width: 0%"></div>
</div>
{%- else -%}
<p class="plynthr-shipping-bar__text">You're <strong>{{ remaining | money }}</strong> away from free shipping!</p>
<div class="plynthr-shipping-bar__track">
<div class="plynthr-shipping-bar__fill" style="width: {{ progress }}%"></div>
</div>
{%- endif -%}
</div>
You can also grab this from the snippet page on Plynthr.
Installation
- In your Shopify admin, go to Online Store → Themes → Edit Code
- Under Snippets, click "Add a new snippet" and name it
plynthr-free-shipping-bar - Paste the code above and hit Save
- Open the file where you want the bar to appear — typically
sections/cart-drawer.liquid,sections/main-cart.liquid, or your announcement bar section - Add this render tag:
{%- render 'plynthr-free-shipping-bar' -%} - Set your free shipping threshold by editing the
free_shipping_thresholdvariable (default is 100) - Save and preview your store
Customisation
All the visual properties are controlled by CSS custom properties (variables) in the :root block. Here's what you can change:
free_shipping_threshold— Your free shipping minimum amount (default: 100)--pfs-bar-color— Progress bar fill colour (default: #10b981, a green)--pfs-bar-complete— Bar colour when threshold is met (default: #059669)--pfs-height— Bar height (default: 8px — try 6px for a thinner look)--pfs-radius— Border radius (default: 20px for rounded, use 4px for squared)--pfs-text-color— Message text colour (default: #333)
Troubleshooting
Bar isn't showing: Make sure the render tag is placed inside a Liquid template file, not a JSON template. Check your theme's structure — if you're on Dawn or a similar theme, the cart drawer is usually in sections/cart-drawer.liquid.
Progress doesn't update when adding items: The bar renders server-side, so it needs a page reload to update. For AJAX cart drawers, you'll need to re-render the snippet via JavaScript after cart updates, or use a fetch('/cart.js') call to get the cart total and update the bar width programmatically.
Currency symbol is wrong: The snippet uses Shopify's money filter, which automatically follows your store's currency settings. If it's showing the wrong format, check Settings → General → Store currency.
Threshold doesn't match your shipping rules: This snippet uses a hardcoded threshold for simplicity. If your free shipping rules are complex (region-based, weight-based), you may need to adjust the logic or use Shopify's native shipping calculator.
Want this done for you?
I'll install this on your Shopify store, test it across devices, and make sure it's working perfectly. Done within 24 hours.