All 20 Countdown Timer sections

See every section

What a campaign counts to

Updated Countdown Timer 1.12.0Tested with WordPress 7.1

Campaigns → a campaign → Countdown. Four choices, under Counts to, and they behave very differently:

  • Fixed date and time. One moment in the calendar. Everybody sees the same clock, and when it passes it is over for everyone at once. Use it for a launch, a Black Friday close, an order-by-Christmas deadline.
  • Product sale end date. Read from WooCommerce per product, including each variation's own dates, so the timer and the price come from the same place. A product with no sale end date shows no timer, which is why this is the right choice for a shop where only some things are reduced. On a variable product the timer starts at the soonest end among the variations on sale, then follows the variation the shopper picks, and hides for one that is not on sale. Only variations a shopper can choose count: one switched off (Enabled unticked), or out of stock where you hide out-of-stock items, is left out, as WooCommerce leaves it out of the product's price. It needs a product to read, so it shows on product pages and listings only: placed only in the bar or above content, the Campaigns list marks it Needs a product placement.
  • Fixed length per visitor. Starts when that visitor first sees it and runs for as long as you set.
  • Daily or weekly cut-off. A time of day on the days you tick — "order within 02:14:09 for dispatch today" before 15:00 on weekdays, or a sale that ends at 18:00 every Friday. Leave every day unticked for every day. When the cut-off passes it counts to the next one straight away, the same for everybody. It is worked out in your site's time zone a day at a time, so 15:00 stays 15:00 on the wall across the clocks changing, and a page carries the next fortnight of cut-offs, so a copy served from a page cache rolls over on its own. It skips the Days off you list, and its heading can say which day it counts to; both are below.

Start date and time is optional on all four. Nothing shows until that moment, so a campaign can be set up days in advance and left alone.

Days off, and the day it ships#

A cut-off on the days you tick knows nothing about Christmas Day or a bank holiday. Without help, on a Friday afternoon it counts to Monday under "for dispatch today", and on a day you are closed it counts to a cut-off nobody is there to meet.

Days off, under Countdown while Counts to is Daily or weekly cut-off, lists the dates the cut-off skips. Add a day off gives a new line: pick the date from the calendar or type it, such as 2026-12-25. Tick Every year beside a date that comes round every year, such as Christmas Day, and it is skipped on that day and month in every year after, without the campaign being touched again. A date that is not every year is taken off the list when you save after it has passed, so the list never fills with last year's holidays. Remove takes a line out.

Under the list, the editor shows the next three cut-offs with your days off applied, such as "Next cut-offs: Tue 29 Dec, Wed 30 Dec, and Thu 31 Dec, at 15:00." It changes as you add, remove or tick dates and as you change the time or the days, before you save, so you can see what a closure does. The Campaigns list says the same for the next one under Counts to: "Next cut-off: Tue 29 Dec, 15:00 (25 and 28 Dec off)", naming the days off it passed over to get there.

A closure is one line per day. A fortnight shut still leaves the timer the fortnight of cut-offs a cached page carries, and a cut-off a month or more away is still found. If every cut-off in the next 76 days is a day off, the timer shows nothing until one is in reach, and the Campaigns list marks the campaign No cut-off ahead rather than Live.

The day it ships. Write {day} in the Heading of a cut-off and it is replaced by the day of the cut-off the timer is counting to:

  • "today" or "tomorrow";
  • the weekday, such as "Tuesday", when it is later in the coming week;
  • the weekday and date, such as "Tuesday 29 December", when it is a week or more away.

So "Order now for dispatch {day}" reads "Order now for dispatch today" on a Monday morning, "…tomorrow" on Sunday evening, and "…Tuesday" at 16:00 on Christmas Eve with Christmas Day and the Monday after it off. The day is your site's, by its own time zone, whatever the clock on the visitor's device says; the word is in the language of the page, and Spanish says "el martes" where English says "Tuesday". A screen reader hears the heading once, with the time left after it: "Order now for dispatch today: 2 hours, 14 minutes remaining".

The word stays right on a page served from a cache. The page carries each of its cut-offs with its date and both of its names, so a copy cached at 23:50 says "today" when it is read at 00:10, and a timer that moves on to the next cut-off names that one's day, without asking your site. {day} works in a cut-off's heading only; in any other kind of campaign it is shown as typed.

Before a scheduled sale starts#

WooCommerce lets you schedule a sale: Sale price dates with a start day still to come. A Product sale end date campaign shows nothing on that product until the sale starts, which is how it has always worked. To bring shoppers back, set Before a scheduled sale starts (under Countdown, once Product sale end date is chosen) to Count down to the start:

  • until the sale starts, the timer counts to the start under Heading before the sale, which reads "Sale starts in" in the shopper's language until you change it. Empty it and the countdown to the start has no heading;
  • at the start it switches to the sale's end and your Heading without reloading, then shows the page once more, which has the sale price once WooCommerce has moved it (see below). A sale with no end date has nothing more to count, so its timer goes at the start;
  • on a variable product's page it counts to the soonest variation's start and follows the variation the shopper picks: to its start, to its end if it is already on sale, or out of sight if it has no sale. A variable product that already has a variation on sale with no end date shows nothing, as before: there is no end to count to, and "Sale starts in" over a product already on sale would not be true. Here too only variations a shopper can choose count: a switched-off one still carrying a sale price does not hide "Sale starts in", and one with a sale to come does not set the countdown;
  • in shop and category listings only simple products show it. A variable product shows nothing there before its sale.

WooCommerce starts a sale at 00:00 of the chosen day in your site's time zone, and moves the product's price to the sale price with a scheduled job of its own. From WooCommerce 10.5 that job runs for each product at its start; before 10.5 it is one daily job, which can run a while after midnight. On a site whose scheduled tasks only run when somebody visits, either can be late. Until the job has run, WooCommerce still shows and charges the regular price. A variable product is different: WooCommerce charges a variation's sale price from the start, but keeps showing the old price, and does not count the product as on sale, so it shows no timer, until its daily job has run. That includes a product with another variation's sale still to come: it does not show "Sale starts in" for that one while a variation shoppers can choose is already on sale. The job for each product at its start skips variations. The plugin never changes a price, so what it does is this:

  • a shopper watching the start is shown the page again two seconds after it. If the price has not moved yet, that page looks once more a minute later, and not again. A shopper who simply opens a page in that minute is never moved on;
  • page caches are emptied at the start, once more a minute later, and again when WooCommerce's own sale job stores the sale price of a product the campaign covers. Nothing else empties them: not an order or a stock update, not a change to a running sale's price, not a product added, imported or put on sale by hand, and not WooCommerce's daily pass over a sale that has already ended. On a network, each site's caches are emptied from that site;
  • a product's own page, and a listing with a simple product on it, drawn while the price has not moved yet is not kept by page caches.

The Campaigns list says Each product's sale start, then its end for a campaign set this way. Nothing about the sale itself changes: the dates and prices are WooCommerce's, and the timer only reads them.

About per-visitor countdowns#

This is the one kind of countdown that can lie, so two things are deliberate.

The start is remembered, in a cookie rather than a session, so it survives a page cache and a closed browser. Somebody who comes back tomorrow finds the offer expired rather than a fresh hour. A timer that resets itself is a timer nobody believes twice, and they only need to notice once.

The visitor's own browser writes that cookie, the moment it draws the timer, and the server reads it on every later page. The server does not send it with a first view, because a response that sets a cookie is one most page caches refuse to keep — Nimble Cache included — and a site-wide per-visitor bar used to stop every page being cached or preloaded. It is only sent from the server where the page is never cached anyway: to a signed-in visitor, or on the cart and checkout. A visitor with JavaScript switched off therefore starts a fresh countdown on each page they open.

It also works on a cached page. The page says how long the countdown is, and the visitor's browser works out their own end from when they first saw it — so nobody inherits the deadline of whoever loaded the page first.

If the offer genuinely does come round again, set Repeat to daily or weekly. A daily campaign starts a new run at midnight in your own time zone, and a weekly one at 00:00 on Monday: the next time the visitor is shown the timer after that, it counts from then. A run that began before midnight counts down to its own end on the page already open.

A start more than five minutes ahead of your site's clock, which a cookie edited by hand can carry, does not count. A linked coupon is refused for it, and the countdown starts again when a page comes straight from your site to a device whose clock agrees with your site's. A copy of the page from a page cache cannot tell such a start from a device clock that runs slow, so there the timer keeps counting to it.

Still stuck? Ask the developers who wrote it. We aim to reply within one business day.