How to Create a Progress Bar on Product Cards
In this article, we will guide you on how to create a progress bar for each product card typically displayed on the Homepage, Collection Page, Product Page, and more.
HOW IT WORKS
The progress bar will display a fake and random value between 80% and 90%, similar to the screenshot above (you can change the values in the code if necessary).
PURPOSE
To remind and show users the products they have personalized but haven't added to the cart yet.
Firstly, to ensure you don't miss any steps, we'll list the files you'll need to create (or edit):
- Layout/theme.liquid
- Snippets/card-product.liquid
- Snippets/teeinblue-progress-bar.liquid
- Assets/teeinblue-progress-bar.js
STEP 1: ENABLED LOADING TEEINBLUE SCRIPTS FOR ALL PAGES
- Go to Store settings > Product page settings > Extras > Turn on the setting "Load scripts on all page outside of product page" > click save to ensure the changes are saved
STEP 2: CREATE PROGRESS BAR FILE
- Go to your Shopify admin > Themes > Actions > Edit code of your published theme.
- From the Snippets folder, select Add a new snippet, name it
teeinblue-progress-bar
, and click Done.
- Copy and paste the liquid code below into the created file, then click **save **to ensure the changes are saved.
<style>
:root {
--progress-bar-height: 10px;
--progress-bar-border-radius: 20px;
--progress-bar-color: #727272;
--progress-bar-bg: #ededed;
--progress-bar-bg-1: #f44336;
--progress-bar-bg-2: #ffc206;
--progress-bar-bg-3: #69c69c;
--progress-bar-bg-4: #69c69c;
--progress-bar-min-height: 20.0px;
}
@keyframes progress-bar-stripes {
from {
background-position: 0 0;
}
to {
background-position: 40px 0;
}
}
#teeinblue-progress-bar{
position: relative;
margin: 0 0 12px 0;
min-height: var(--progress-bar-min-height);
padding: 0 20px;
}
#teeinblue-progress-bar .progress{
position: relative;
margin: 0 0 10px 0;
font-size: 0;
letter-spacing: 0;
}
#teeinblue-progress-bar .progress.progress-hidden{
display: none;
}
#teeinblue-progress-bar .progress .progress_shipping{
height: var(--progress-bar-height);
background-color: var(--progress-bar-bg);
border-radius: var(--progress-bar-border-radius);
border: 0;
}
#teeinblue-progress-bar .progress .progress-meter{
position: relative;
display: block;
width: 100%;
height: 100%;
font-size: 13px;
font-weight: 400;
letter-spacing: 0;
line-height: 11px;
color: #ffffff;
transition: width .3s ease;
}
#teeinblue-progress-bar .progress.progress-free .progress_shipping{
border-color: var(--progress-bar-bg-4);
}
#teeinblue-progress-bar .progress.progress-80 .progress_shipping{
border-color: var(--progress-bar-bg-1);
}
#teeinblue-progress-bar .progress.progress-90 .progress_shipping{
border-color: var(--progress-bar-bg-2);
}
#teeinblue-progress-bar .progress.progress-100 .progress_shipping{
border-color: var(--free_shipping_color3);
}
#teeinblue-progress-bar .progress.progress-free .progress-meter{
background-color: var(--progress-bar-bg-4);
}
#teeinblue-progress-bar .progress.progress-80 .progress-meter{
background-color: var(--progress-bar-bg-1);
}
#teeinblue-progress-bar .progress.progress-90 .progress-meter{
background-color: var(--progress-bar-bg-2);
}
#teeinblue-progress-bar .progress.progress-100 .progress-meter{
background-color: var(--progress-bar-bg-3);
}
#teeinblue-progress-bar .message{
font-size: 14px;
font-weight: 400;
letter-spacing: 0;
line-height: 24px;
color: #727272;
transition: color 350ms ease-in-out;
}
#teeinblue-progress-bar .progress.progress-free + .message {
color: var(--progress-bar-bg-4);
}
#teeinblue-progress-bar .message .text{
text-transform: capitalize;
}
#teeinblue-progress-bar .progress .progress-meter {
text-align: center;
animation: 2s linear 0s infinite progress-bar-stripes;
background-image: linear-gradient(45deg,rgba(255,255,255,.15) 25%,transparent 25%,transparent 50%,rgba(255,255,255,.15) 50%,rgba(255,255,255,.15) 75%,transparent 75%,transparent);
background-size: 40px 40px;
transition: .9s linear;
transition-property: width,background-color;
border-radius: var(--progress-bar-border-radius);
}
</style>
<teeinblue-progress-bar id="teeinblue-progress-bar" data-product-id="{{ product.id }}" style="display: none">
<div class="progress none progress-80" data-text-enabled="false" data-progress>
<div class="progress_shipping" role="progressbar">
<div class="progress-meter" style="width: 9%;" data-progress-bar-progress-meter>
<div class="text"></div>
</div>
</div>
<div class="message" data-progress-message><span class="text">Your gift is almost complete.</span></div>
</div>
</teeinblue-progress-bar>
STEP 3: DETERMINE WHERE TO DISPLAY THE PROGRESS BAR
- In this guide, we'll help you display the Progress bar at the bottom of each Product Card
- From the Snippets folder, find the "card-product.liquid" file. Alternatively, you can search for
card-product
in the file search box at the top
- Inside the "card-product.liquid" file, copy and paste the following liquid code below line 343, then click save to ensure the changes are saved
{% render 'teeinblue-progress-bar', product: card_product %}
```

| You can place that liquid code anywhere in the card-product file if you want it to display elsewhere, ensuring it doesn't break the layout of the product card
* On the storefront, the progress bar will display below `card__content`

|| There may be cases where the theme you're using doesn't use the `card_product` variable, causing the progress bar not to work. In that case, you'll need to find out what variable they're using for the Product object by pressing `Ctrl+F` (`Command + F` for MacOS), searching for keywords like `compare_at_price` or any properties of the Product object to see what variables they've declared for the Product object. Then, replace `card_product` with that variable
|| 
# STEP 4: CREATE THE JS FILE FOR THE PROGRESS BAR
* From the **Assets** folder, select **Add a new asset**, create a blank file with the JS extension, name it `teeinblue-progress-bar`, and click **Done**

* Copy and paste the js code below into the created file, then click **save** to ensure the changes are saved
class TeeinblueProgressBar extends HTMLElement {
constructor() {
super();
}
static classLabel1 = 'progress-80';
static classLabel2 = 'progress-90';
connectedCallback() {
this.freeShippingEligible = 0;
this.progressBar = this.querySelector('[data-progress]');
this.textEnabled = this.progressBar?.dataset.textEnabled === 'true';
this.progressMeter = this.querySelector('[data-progress-bar-progress-meter]');
this.calculateProgress();
this.initialize();
}
initialize() {
const gridItems = document.querySelectorAll("#teeinblue-progress-bar");
gridItems.forEach(item => {
const gridItemId = item.getAttribute('data-product-id');
if (!gridItemId) return;
if (window.teeinblue.hasCustomization(gridItemId.toString())) item.style.display = 'block';
});
}
calculateProgress() {
let freeProgressBar = Math.random() < 0.5 ? 80 : 90;
const classLabel = freeProgressBar === 80 ? TeeinblueProgressBar.classLabel1 : TeeinblueProgressBar.classLabel2;
this.setProgressWidth(freeProgressBar, classLabel);
}
resetProgressClass(classLabel) {
this.progressBar.classList.remove('progress-80', 'progress-90', 'progress-free');
this.progressBar.classList.add(classLabel);
}
setProgressWidth(freeProgressBar, classLabel) {
setTimeout(() => {
this.resetProgressClass(classLabel);
this.progressMeter.style.width = ${freeProgressBar}%
;
if (this.textEnabled) this.progressMeter.querySelector('.text').innerHTML = ${freeProgressBar}%
;
}, 400);
}
}
window.addEventListener('load', () => {
customElements.define('teeinblue-progress-bar', TeeinblueProgressBar);
});
# Step 5: IMPORT THE JS FILE INTO "theme.liquid"
* From the **Layout** folder, find the **"theme.liquid"** file, add the following code line above the `</body>` tag, then click **save** to ensure the changes are saved
<script src="{{ 'teeinblue-progress-bar.js' | asset_url }}" defer="defer"></script>

# CHECK THE STOREFRONT TO ENSURE THE PROGRESS BAR IS WORKING
* First, go to a **Product page** and personalize it.
* Then, open the **Homepage **and **Collection Page **to see if the personalized product displays the Progress Bar.
# FINAL NOTES
|| Our provided code may not work with all themes; we'll strive to improve it in the future.
|| If you need assistance with this feature, please contact the support team, and we'll be happy to help.
Updated on: 18/03/2024
Thank you!