Most cart abandonments happen in the gap between “I think I have enough” and “wait, shipping costs how much?” The shopper adds one item, sees the shipping fee at checkout, and leaves. A free shipping progress bar fixes this by showing them exactly how close they are to unlocking free shipping while they are still shopping, not at checkout.

Why This Works

When shoppers can see they are $8 away from free shipping, they do not abandon. They browse for one more item. The progress bar creates a micro-goal that feels achievable. It turns shipping from a penalty into a reward.

The best part? You do not need a plugin for this. You can build it with a small amount of liquid code in your theme and a snippet of JavaScript. Here is how.

Step 1: Set Your Free Shipping Threshold

Before you build anything, decide your threshold. Look at your average order value over the last 90 days. Set your free shipping threshold about 15 to 20 percent above that number. If your average order is $65, set free shipping at $80. This gives shoppers a realistic target that lifts your average order value without feeling unreachable.

Write this number down. You will use it in the code in step 3.

Step 2: Find Your Cart Template

Go to your Shopify admin. Click Online Store, then Themes. Click the three dots next to your active theme and select Edit code. In the Sections folder, find your cart template. This is usually called cart-template.liquid or main-cart.liquid depending on your theme.

If you are using a drawer cart (the slide-out cart that appears when someone clicks add to cart), look for cart-drawer.liquid or similar in your Snippets folder.

Step 3: Add the Progress Bar HTML

Inside your cart template, find the section where the cart subtotal or total is displayed. Right above that block, paste this code:

<div class=”free-shipping-bar” data-threshold=”8000″>
  <div class=”free-shipping-track”>
    <div class=”free-shipping-fill” style=”width: 0%”></div>
  </div>
  <p class=”free-shipping-text”>Add <span class=”free-shipping-remaining”>$80</span> more for free shipping</p>
</div>

Note: the data-threshold value is in cents. $80 becomes 8000. Adjust this to match your threshold.

Step 4: Add the CSS

In your theme CSS file (usually in the Assets folder as base.css or theme.css), add these styles:

.free-shipping-bar {
  margin: 16px 0;
  padding: 12px;
  background: #f5f5f5;
  border-radius: 8px;
  text-align: center;
}
.free-shipping-track {
  height: 8px;
  background: #e0e0e0;
  border-radius: 4px;
  overflow: hidden;
  margin-bottom: 8px;
}
.free-shipping-fill {
  height: 100%;
  background: #000;
  border-radius: 4px;
  transition: width 0.4s ease;
}
.free-shipping-text {
  font-size: 14px;
  margin: 0;
  color: #333;
}
.free-shipping-bar.is-unlocked .free-shipping-text {
  font-weight: 600;
  color: #1a7a3a;
}

Adjust the colours to match your brand. The .is-unlocked class changes the text when the threshold is met.

Step 5: Add the JavaScript

This is the part that makes it dynamic. The script reads the current cart total, calculates how far the shopper is from the threshold, and updates the bar in real time. Add this script at the bottom of your cart template, inside a {% javascript %} tag or in your theme JavaScript file:

document.addEventListener(“DOMContentLoaded”, function() {
  const bar = document.querySelector(“.free-shipping-bar”);
  if (!bar) return;

  const threshold = parseInt(bar.dataset.threshold, 10);

  function updateBar() {
    fetch(“/cart.js”)
      .then(res => res.json())
      .then(cart => {
        const total = cart.total_price;
        const remaining = Math.max(threshold – total, 0);
        const percent = Math.min((total / threshold) * 100, 100);

        bar.querySelector(“.free-shipping-fill”).style.width = percent + “%”;
        bar.querySelector(“.free-shipping-remaining”).textContent = “$” + (remaining / 100).toFixed(0);

        if (remaining === 0) {
          bar.classList.add(“is-unlocked”);
          bar.querySelector(“.free-shipping-text”).innerHTML = “You unlocked free shipping!”;
        }
      });
  }

  updateBar();
  document.addEventListener(“cart:updated”, updateBar);
  document.addEventListener(“ajaxCart:updated”, updateBar);
});

The script fetches the cart total on load and listens for cart update events. This means the bar updates instantly when a shopper adds or removes an item, without a page reload.

Step 6: Test It

Add a product to your cart. Open the cart page or drawer. You should see the progress bar with the remaining amount. Add more products and watch the bar fill up. When you cross the threshold, the text should change to confirm free shipping is unlocked.

Check on mobile too. The bar should be fully responsive. If it looks cramped, reduce the padding in the CSS for mobile breakpoints.

Step 7: Add a Product Recommendation Below the Bar

This is where the bar earns its keep. When a shopper sees they need $12 more for free shipping, show them products in that price range. You can add a simple product carousel below the bar using your theme’s existing product recommendation snippet.

In your cart template, below the progress bar HTML, add a conditional block that shows products priced near the remaining amount. This gives the shopper exactly what they need to cross the threshold.

Common Mistakes to Avoid

Setting the threshold too high. If your average order is $40 and you set free shipping at $100, no one will chase it. Keep it within 20 percent of your average order value.

Forgetting to update the bar on cart changes. If the bar only updates on page load, shoppers who add items via AJAX will not see it update. The JavaScript event listeners in step 5 handle this.

Hiding the bar on mobile. Mobile shoppers are the most likely to abandon over shipping costs. The bar should be even more visible on mobile, not less.

Not testing with real products. Add items at different price points and make sure the math works. A rounding error in the remaining amount will make the bar feel broken.

What to Track After Launch

Give it two weeks. Then check these numbers in your Shopify admin:

  • Average order value (compare to the two weeks before the bar)
  • Cart abandonment rate at checkout
  • Percentage of orders that qualify for free shipping

If your average order value goes up by even 5 percent, the bar has paid for the 30 minutes you spent building it.


Want more like this? Join MOKU Club for free. Weekly resources, early access to new guides, and occasional templates you can actually use. Join below.

AI for Product Return Analysis: How Small Businesses Spot Why Customers Send Things Back Without Reading Every Return RequestAi

AI for Product Return Analysis: How Small Businesses Spot Why Customers Send Things Back Without Reading Every Return Request

HeraHeraOctober 5, 2026
Your Competitors Are Using AI to Watch Your Prices in Real Time. Here’s How to Keep Up.AiMarketing

Your Competitors Are Using AI to Watch Your Prices in Real Time. Here’s How to Keep Up.

HeraHeraMay 19, 2026
AI for Customer Service: How Small Businesses Cut Response Times in Half Without HiringAiTips & Tricks

AI for Customer Service: How Small Businesses Cut Response Times in Half Without Hiring

HeraHeraMay 31, 2026