How to Add a Promotion Countdown to Your Shopify Store
avatarAnne
03-18-2026 6:54 AM

Why Use a Countdown Timer on Your Product Page

In ecommerce, urgency is a powerful driver of customer behavior. According to behavioral psychology, consumers are more likely to take action when they perceive scarcity or limited time offers (Cialdini, Influence: The Psychology of Persuasion). Countdown timers serve exactly this purpose.

Adding a countdown timer to your product page can:

  • Encourage faster purchasing decisions

  • Reduce cart abandonment

  • Highlight special promotions such as flash sales, seasonal discounts, or product launches

For example, showing "Sale ends in 03:12:45" signals to customers that they need to act fast, increasing the likelihood of conversion.


How to Add a Countdown Timer in Shopify

Before adding any code, it is highly recommended to duplicate your theme in Shopify. This ensures that your live store is safe if any mistakes occur during editing.

Step 1 Copy Your Theme

  1. Go to Online Store > Themes

  2. Click Actions > Duplicate

  3. Work on the duplicated theme to avoid affecting your live store


Step 2 Add the Countdown Code

1. Add Liquid Block

Create a new snippet named product-countdown.liquid and paste the following code:

 {% assign countdown_type = block.settings.countdown_type %}
{% assign countdown_time = block.settings.countdown_time %}
{% assign countdown_collection = block.settings.countdown_collection %}
{% assign countdown_style = block.settings.countdown_style %}

<div
    class="product-countdown-wrapper"
    data-countdown-id="{{ product.id }}"
>
    <div
        class="product-countdown-text"
        data-countdown-text="{{ block.settings.countdown_text }}"
    >
    </div>
    {%- if countdown_type == 'all_product' -%}
        <div
            class="product-countdown style-{{ countdown_style }}"
            data-countdown="{{ countdown_time }}"
        >
        </div>
    {%- elsif countdown_type == 'collection_product' -%}
        {%- liquid
            assign has_countdown = false
            if countdown_collection != blank
                for collection in product.collections
                    assign collection_handle = collection.handle
                    echo 'collection_handle: ' | append: collection_handle
                    if collection_handle == countdown_collection
                        assign has_countdown = true
                    endif
                endfor
            endif
        -%}
        {%- if has_countdown -%}
            <div
                class="product-countdown style-{{ countdown_style }}"
                data-countdown="{{ countdown_time }}"
            >
            </div>
        {%- endif -%}
    {%- else -%}
        {%- if product.metafields.c_f.countdown -%}
            {% assign metafields_countdown_time = product.metafields.c_f.countdown %}
            <div
                class="product-countdown style-{{ countdown_style }}"
                data-countdown="{{ metafields_countdown_time }}"
            >
            </div>
        {%- endif -%}
    {%- endif -%}      
</div>
{% stylesheet %}
.product-countdown-wrapper {
    overflow: hidden;
    font-size: 0px;
}
.product-countdown-text {
    opacity: 0;
    transition: opacity 350ms ease;
}
.product-countdown-text.show {
    opacity: 1;
}
.product-countdown-text span {
    display: block;
    color: #cb0000;
    font-size: 14px;
    margin-bottom: 10px;
}
.product-countdown {
    display: inline-block;
    vertical-align: top;
    font-size: 0;
    letter-spacing: 0;
    text-align: left;
    transition: opacity 350ms ease, visibility 350ms ease, transform 350ms ease;
    opacity: 0;
    visibility: hidden;
    transform: translate3d(0, 110%, 0);
}
.product-countdown.show {
    opacity: 1;
    visibility: visible;
    transform: translate3d(0, 0%, 0);
}

.product-countdown.style-1 .num + .num {
    margin-left: 5px;
}

.product-countdown.style-1 .num {
    display: inline-block;
    color: #333333;
    font-size: 12px;
    font-weight: 500;
    border: 2px solid #f1f1f1;
    border-radius: 4px;
    background-color: transparent;
    text-align: center;
    min-width: 56px;
    padding: 10px;
}
.product-countdown.style-1 span {
    color: #3d3d3d;
    font-size: 12px;
    font-weight: normal;
    display: block;
    text-transform: capitalize;
}
.product-countdown.style-2 {
    border: 1px solid #e8e8e8;
    border-radius: 5px;
}
.product-countdown.style-2 .num {
    display: inline-block;
    color: #333333;
    font-weight: 500;
    border: none;
    border-radius: 0;
    background-color: transparent;
    text-align: center;
    min-width: 75px;
    min-height: 70px;
    font-size: 16px;
    padding: 10px;
}
.product-countdown.style-2 .num + .num {
    min-width: 76px;
    border-left: 1px solid #e8e8e8;
    margin-left: 0;
}
.product-countdown.style-2 .num:last-child {
    min-width: 75px;
}
.product-countdown.style-2 .num span {
    color: #3d3d3d;
    font-weight: normal;
    display: block;
    text-transform: capitalize;
    font-size: 12px;
}

{% endstylesheet %}

<script src="{{ 'product-countdown.js' | asset_url }}" defer></script>

{% schema %}
{
  "name": "Countdown",
  "tag": null,
  "settings": [
    {
        "type": "select",
        "id": "countdown_type",
        "default": "all_product",
        "label": "Countdown Type",
        "options": [
            {
            "value": "all_product",
            "label": "For All Products"
            },
            {
            "value": "different_product",
            "label": "For Each Product"
            },
            {
            "value": "collection_product",
            "label": "For Collection"
            }
        ]
    },
    {
        "type": "collection",
        "id": "countdown_collection",
        "label": "Collection"
    },
    {
        "type": "text",
        "id": "countdown_text",
        "label": "Countdown Text",
        "default": "Hurry Up! Offer ends in:"
    },
    {
        "type": "text",
        "id": "countdown_time",
        "label": "Countdown Time",
        "default": "Sep 31, 2025 18:00:00",
    },
        {
        "type": "select",
        "id": "countdown_style",
        "label": "Countdown Style",
        "default": "1",
        "options": [
            {
                "value": "1",
                "label": "1"
            },
            {
                "value": "2",
                "label": "2"
            }
        ]
    }
  ],
  "presets": [
    {
      "name": "Countdown",
      "category": "t:categories.product"
    }
  ]
}
{% endschema %}

2. Add JavaScript

Upload product-countdown.js to your Assets folder with this content:

 (function () {
    let countdownfunction = null;
    function startCountdown() {
        // Ensure that the wrapper DOM element exist
        const countDownWrapperDom = document.querySelector('[data-countdown-id]');
        if (!countDownWrapperDom) {
            console.error('Countdown wrapper element not found');
            return;
        }
        // Ensure that the countdown DOM element exist
        const countDownDom = countDownWrapperDom.querySelector('[data-countdown]');
        if (!countDownDom) {
            console.error('Countdown display element not found');
            return;
        }
        const countDownTime = countDownDom.getAttribute('data-countdown');
        const countDownDate = new Date(countDownTime).getTime();

        // Ensure that the countdown text DOM element exist
        const countDownTextDom = countDownWrapperDom.querySelector('.product-countdown-text');
        if (!countDownTextDom) {
          console.error('Countdown text element not found');
          return;
        }
        const countDownText = countDownTextDom.getAttribute('data-countdown-text');

        // Check if the countdown time exist
        if (!countDownTime) {
            console.error('Countdown date not found');
            return;
        }

        // Clear the previous timer (if any)
        if (countdownfunction) {
            clearInterval(countdownfunction);
        }

        // Set timer and save reference
        countdownfunction = setInterval(updateCountdown, 1000);

        function updateCountdown() {
            const now = new Date().getTime();
            const distance = countDownDate - now;

            if (distance < 0) {
                clearInterval(countdownfunction);
                console.log('Countdown ended');
                countDownDom.innerHTML = '';
                countDownTextDom.innerHTML = '';
                countdownfunction = null;
                return;
            }

            const days = Math.floor(distance / (1000 * 60 * 60 * 24));
            const hours = Math.floor((distance % (1000 * 60 * 60 * 24)) / (1000 * 60 * 60));
            const minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
            const seconds = Math.floor((distance % (1000 * 60)) / 1000);

            const strCountDown = `
                <span class="num">${days}<span>Days</span></span>
                <span class="num">${hours}<span>Hours</span></span>
                <span class="num">${minutes}<span>Mins</span></span>
                <span class="num">${seconds}<span>Secs</span></span>
            `;

            console.log('Countdown:', days, hours, minutes, seconds);
            // Update the content and display status of text prompt elements
            countDownTextDom.innerHTML = `<span>${countDownText}</span>`;
            countDownTextDom.classList.add('show');

            // Update the content and display status of the countdown display element
            countDownDom.innerHTML = strCountDown;
            countDownDom.classList.add('show');
        }
    }

    startCountdown();
})();

Step 3 Configure and Use the Countdown

Once your code is in place, you can configure it directly in Theme Editor.

  1. Go to Online Store > Themes > Customize

  2. Open a product page

  3. Add the Countdown block (or section) to your page

  4. Configure settings:

    • Countdown Type: For all products / For collection / For product

    • Collection: If type is collection-specific

    • Countdown Text: e.g., "Hurry Up! Offer ends in"

    • Countdown Time: e.g., Sep 30, 2026 18:00:00

    • Countdown Style: Choose your preferred design

This will instantly display the countdown timer on the product page according to your selected configuration.

⚠️ Note

  • The countdown will only display if the date is greater than or equal to the current date. If the block does not show after adding it, please check your date setting first.

  • When using For Collection, the countdown will only appear on product pages that belong to the selected collection. It will not display on products outside of that collection.

  • When using For Each Product, you must set a value in the product metafield c_f.countdown. If no date is configured, the countdown will not display.

How to Set Up Metafields for Product-Specific Countdown

When using a countdown for individual products, you need to create a metafield to store the countdown time.

Follow these steps in your Shopify admin:

  1. Go to Settings > Metafields & Metaobjects

  2. Click Products

  3. Click Add definition

Then configure the metafield as follows:

  • Name: countdown

  • Namespace and key: c_f.countdown

  • Type: Date and time

⚠️ Important
When creating the metafield, Shopify will generate a default key automatically. You must manually edit it and change it to c_f.countdown. If the key does not match this exactly, the countdown will not work.


Countdown timers are a simple but effective way to increase urgency and drive sales on your Shopify store. By following this guide, you can implement a flexible, fully theme-based countdown timer without relying on paid apps.

For any questions or further assistance, please don't hesitate to reach out. Simply leave us a message, and we will respond to you as soon as possible. We're here to help and look forward to working with you!