How can I add a countdown timer to my site?

I would like to show a live updating countdown timer on my site leading up to a special offer. I can see blocks in BlockLab to achieve this but I want to do something a little different…any suggestions on where to start?

Hi there,

If you want to use custom code to add a countdown timer to your site, a little HTML with some JavaScript can do this for you.

Example 1: Countdown to a future date/time

Example:

How to do this…

  1. In BlockLab, add a HTML block with the following contents:
<div id="freeDeliveryCountdown" stlye="display:none">
Get 10% off with code <b>TENOFF</b>.
Limited time only - expires in <span>2023-05-24 16:00:00</span>
</div>

<script>
setInterval(() => {
    const span = document.querySelector('#freeDeliveryCountdown span');
    const target = span.dataset.target ? new Date(span.dataset.target) : (span.dataset.target = span.textContent, new Date(span.textContent));
    const diff = Math.max(0, Math.floor((target - new Date()) / 1000));
    span.textContent = `${Math.floor(diff / 60)} min ${diff % 60}s`;
    span.parentElement.style.display = 'block';
}, 1000);
</script>

Example 2: Countdown to the same time everyday

Example:

If you would like your countdown timer to change every day and show the time remaining until a special time, such as a 4pm next-day delivery cut-off time, we can do something different.

How to do this…

In BlockLab, add a HTML block with the following contents for example:

<div id="freeDeliveryCountdown">
Time left for next-day delivery: <span>4pm</span>
</div>

<script>
setInterval(_ => {
    const span = document.querySelector('#freeDeliveryCountdown span');
    const targetTime = span.dataset.time || span.textContent;
    span.dataset.time = targetTime;
    const [hourStr, period] = targetTime.split(/(am|pm)/i);
    let targetHour = parseInt(hourStr);
    if (period.toLowerCase() === 'pm' && targetHour < 12) targetHour += 12;
    if (period.toLowerCase() === 'am' && targetHour === 12) targetHour = 0;

    const current = new Date();
    let target = new Date();
    target.setHours(targetHour, 0, 0);
    if (current > target) target.setDate(target.getDate() + 1);
    
    const diff = Math.max(0, Math.floor((target - current) / 1000));
    const hrs = Math.floor(diff / 3600);
    const mins = Math.floor(diff / 60) % 60;
    const secs = diff % 60;
    span.textContent = `${hrs > 0 ? `${hrs}hrs ` : ''}${mins}mins ${secs}sec`;
    span.parentElement.style.display = 'block';
}, 1000);
</script>

Summary

Both of these examples use setInterval JavaScript to repeat the code every second (1000ms).

In both examples, simply change the information in the <span></span> element to the desired date or time.

1 Like

That’s great, thanks!

However - I want something like Example 2 but where some days are excluded, so for example if saturday/sunday are excluded, on a Friday after 4pm the countdown will be counting down to Monday at 4pm instead of Saturday, if that makes sense?

Understood. For your situation perhaps something a little more sophisticated can be done to show how specific days could be treated differently.

Example 3: Daily countdown with some days excluded

This one would look identical to Example 2 above, but now the HTML could be:

<div id="freeDeliveryCountdown">
Time left for next-day delivery: <span data-days="mon,tue,wed,thu,fri">4pm</span>
</div>

<script>
setInterval(_ => {
    const s = document.querySelector('#freeDeliveryCountdown span');
    const [hStr, p] = (s.dataset.t = s.dataset.t || s.textContent).split(/(am|pm)/i);
    let h = parseInt(hStr);
    h += (p.toLowerCase() === 'pm' && h < 12 ? 12 : 0) - (p.toLowerCase() === 'am' && h === 12 ? 12 : 0);
    const c = new Date(), t = new Date(), days = ['sun', 'mon', 'tue', 'wed', 'thu', 'fri', 'sat'];
    let availableDays = (s.dataset.days || '').split(',').map(d => d.trim().toLowerCase());
console.log(availableDays);
    t.setHours(h, 0, 0);
    if (c > t || !availableDays.includes(days[c.getDay()])) {
        do {
            t.setDate(t.getDate() + 1);
        } while (!availableDays.includes(days[t.getDay()]));
    }
    const d = Math.max(0, Math.floor((t - c) / 1000)), hrs = Math.floor(d / 3600), mins = Math.floor(d / 60) % 60, secs = d % 60;
    s.textContent = `${hrs > 0 ? `${hrs}hrs ` : ''}${mins}mins ${secs}sec`;
    s.parentElement.style.display = 'block';
}, 1000);
</script>

With this alternative approach, your <span> can now have specific days, so for example the countdown timer would only be counting down to 4pm “today” if it was included in the list of days. In the example we’ve used <span data-days="mon,tue,wed,thu,fri">4pm</span> so that every day except the weekend is included.