How to Add a Sale Countdown Timer to Your WooCommerce Single Products Page?

Want to add a sleek countdown timer to your WooCommerce product sales? You’re in the right place! Today, I’ll show you how to add a professional-looking countdown timer that shows your customers exactly how long they have until a sale ends. The best part? It works for simple and tricky variable products with different variations.

What Does This Code Do?

Let me break it down in simple terms:

  • Creates a countdown timer that shows days, hours, minutes, and seconds
  • Automatically appears when a product is on sale
  • Disappears when the sale ends
  • Works with both regular products and products with variations
  • Looks clean and professional with minimal styling

What You’ll See?

Once activated, you’ll see a nice countdown timer appear automatically on any product that’s on sale with an end date set. The timer shows:

  • Days remaining
  • Hours
  • Minutes
  • Seconds

The timer updates in real-time, and when the sale ends, the timer is hidden automatically.

See the screenshot here below.

How to Add the Code to Your Site?

There are two ways to add this code to your WordPress site:

  1. Adding it to your child theme’s functions.php file
  2. Using the Code Snippets plugin (my recommended method!)

Why I Recommend Code Snippets Plugin

Here’s why Code Snippets is the way to go:

  • Safer: If you make a mistake, it won’t break your entire site
  • Theme Independent: Your code stays active even if you change themes
  • Organized: Each piece of code is separate and easy to manage
  • Easy to Disable: Just click a button to turn features on/off
  • No FTP Required: Everything happens right in your WordPress dashboard

When you add code directly to functions.php, it’s tied to your theme. Switch themes? Poof! Your code is gone. Plus, one tiny typo could make your whole site go blank – yikes!

Video: How to Add a Sale Countdown Timer to Your WooCommerce Products Page?

Installation Steps

1. First, install the “Code Snippets” plugin:

    • Go to Plugins → Add New in your WordPress dashboard
    • Search for “Code Snippets”
    • Click “Install Now” then “Activate”

    2. Add the PHP code:

      • Go to Snippets → Add New
      • Give it a title like “WooCommerce Sale Countdown”
      • Copy and paste the PHP code (see here below) into the editor
      • Check “Only run in frontend area” is CHECKED
      • Click “Save Changes and Activate”
      // Add sale end date to variation data and pass it via wp_localize_script
      add_action('woocommerce_single_product_summary', 'custom_sale_end_timer', 25);
      
      function custom_sale_end_timer() {
          global $product;
      
          // Pre-fetch sale dates for variations if it's a variable product
          if( $product->is_type('variable') ) {
              $sale_dates = array();
              $variation_ids = $product->get_visible_children(); // Get visible variation IDs
              
              foreach( $variation_ids as $variation_id ) {
                  $variation = wc_get_product( $variation_id );
      
                  if( $variation->is_on_sale() ) {
                      $date_on_sale_from = $variation->get_date_on_sale_from();
                      $date_on_sale_to   = $variation->get_date_on_sale_to();
                      
                      if( ! empty($date_on_sale_from) || ! empty($date_on_sale_to) ) {
                          $sale_dates[$variation_id] = array(
                              'from' => $date_on_sale_from ? $date_on_sale_from->getTimestamp() : '',
                              'to'   => $date_on_sale_to ? $date_on_sale_to->getTimestamp() : '',
                          );
                      }
                  }
              }
      
              // Pass the sale dates to the frontend JavaScript
              wc_enqueue_js( "
                  var variationSaleDates = " . json_encode($sale_dates) . ";
                  var countdownInterval = null;
      
                  jQuery(document).ready(function($) {
                      // Function to update the countdown timer
                      function updateCountdown(saleEndDate) {
                          var now = new Date().getTime();
                          var timeLeft = (saleEndDate - now) / 1000;
      
                          var days = Math.floor(timeLeft / 86400);
                          var hours = Math.floor((timeLeft % 86400) / 3600);
                          var minutes = Math.floor((timeLeft % 3600) / 60);
                          var seconds = Math.floor(timeLeft % 60);
      
                          if (timeLeft > 0) {
                              $('.custom-sale-countdown .days .value').text(days.toString().padStart(2, '0'));
                              $('.custom-sale-countdown .hours .value').text(hours.toString().padStart(2, '0'));
                              $('.custom-sale-countdown .mins .value').text(minutes.toString().padStart(2, '0'));
                              $('.custom-sale-countdown .secs .value').text(seconds.toString().padStart(2, '0'));
                          } else {
                              $('.custom-sale-countdown .countdown').text('Sale Ended');
                              clearInterval(countdownInterval); // Clear interval when sale ends
                          }
                      }
      
                      // Clear any previous countdown interval
                      function clearPreviousCountdown() {
                          if (countdownInterval) {
                              clearInterval(countdownInterval);
                              countdownInterval = null;
                          }
                      }
      
                      // Handle variable product variation selection
                      $('form.variations_form').on('found_variation', function(event, variation) {
                          var variationId = variation.variation_id;
      
                          // Check if the selected variation has a sale date
                          if (variationSaleDates[variationId] && variationSaleDates[variationId].to) {
                              var saleEndDate = new Date(variationSaleDates[variationId].to * 1000);
      
                              // Clear any existing interval to prevent multiple countdowns
                              clearPreviousCountdown();
      
                              // Immediately update countdown once
                              updateCountdown(saleEndDate);
      
                              // Update countdown every second
                              countdownInterval = setInterval(function() {
                                  updateCountdown(saleEndDate);
                              }, 1000);
      
                              // Show countdown if hidden
                              $('.custom-sale-countdown').show();
                          } else {
                              // Hide countdown if no sale
                              clearPreviousCountdown();
                              $('.custom-sale-countdown').hide();
                          }
                      });
                  });
              ");
      
              // Display countdown HTML structure, hidden initially
              echo '<div class="custom-sale-countdown" style="display: none;">
                      <h3>Sale ends in</h3>
                      <div class="countdown">
                          <span class="days">
                              <span class="value">00</span>
                              <span class="countdown-label">Days</span>
                          </span>
                          :
                          <span class="hours">
                              <span class="value">00</span>
                              <span class="countdown-label">Hours</span>
                          </span>
                          :
                          <span class="mins">
                              <span class="value">00</span>
                              <span class="countdown-label">Min</span>
                          </span>
                          :
                          <span class="secs">
                              <span class="value">00</span>
                              <span class="countdown-label">Sec</span>
                          </span>
                      </div>
                  </div>';
          }
      
          // Handle simple products
          if ($product->is_on_sale() && $product->get_date_on_sale_to()) {
              $sale_end_date = $product->get_date_on_sale_to()->getTimestamp();
      
              wc_enqueue_js( "
                  jQuery(document).ready(function($) {
                      var saleEndDate = new Date($sale_end_date * 1000);
      
                      function updateCountdown() {
                          var now = new Date().getTime();
                          var timeLeft = (saleEndDate - now) / 1000;
      
                          var days = Math.floor(timeLeft / 86400);
                          var hours = Math.floor((timeLeft % 86400) / 3600);
                          var minutes = Math.floor((timeLeft % 3600) / 60);
                          var seconds = Math.floor(timeLeft % 60);
      
                          if (timeLeft > 0) {
                              $('.custom-sale-countdown .days .value').text(days.toString().padStart(2, '0'));
                              $('.custom-sale-countdown .hours .value').text(hours.toString().padStart(2, '0'));
                              $('.custom-sale-countdown .mins .value').text(minutes.toString().padStart(2, '0'));
                              $('.custom-sale-countdown .secs .value').text(seconds.toString().padStart(2, '0'));
                          } else {
                              $('.custom-sale-countdown .countdown').text('Sale Ended');
                              clearInterval(countdownInterval); // Clear interval when sale ends
                          }
                      }
      
                      // Immediately update countdown once
                      updateCountdown();
      
                      // Update countdown every second
                      var countdownInterval = setInterval(updateCountdown, 1000);
                  });
              ");
      
              // Display countdown HTML structure for simple products
              echo '<div class="custom-sale-countdown">
                      <h3>Sale ends in</h3>
                      <div class="countdown">
                          <span class="days">
                              <span class="value">00</span>
                              <span class="countdown-label">Days</span>
                          </span>
                          :
                          <span class="hours">
                              <span class="value">00</span>
                              <span class="countdown-label">Hours</span>
                          </span>
                          :
                          <span class="mins">
                              <span class="value">00</span>
                              <span class="countdown-label">Min</span>
                          </span>
                          :
                          <span class="secs">
                              <span class="value">00</span>
                              <span class="countdown-label">Sec</span>
                          </span>
                      </div>
                  </div>';
          }
      }

      3. Add the CSS:

        • Go to Snippets → Add New again
        • Create a new snippet called “WooCommerce Sale Countdown CSS”
        • Paste the CSS code (the styling part)
        • Change the snippet type to “CSS”
        • Save and activate
        .custom-sale-countdown {
            text-align: left;
            margin-bottom: 20px;
            font-weight: bold;
            color: #333;
        }
        .custom-sale-countdown h3 {
            font-size: 18px;
            margin-bottom: 10px;
        }
        .custom-sale-countdown .countdown {
            display: flex;
            justify-content: flex-start; 
            gap: 10px;
            font-size: 32px;
            letter-spacing: 2px;
        }
        
        .custom-sale-countdown .countdown span {
            display: flex;
            flex-direction: column;
            align-items: center;
            justify-content: center;
            padding: 5px 10px;
            background-color: #f8f9fa;
            border-radius: 5px;
            color: #000;
            font-size: 24px;
            border: none; /* Remove the border */
        }
        .custom-sale-countdown .countdown span .countdown-label {
            font-size: 12px; /* Smaller label size */
            font-weight: normal;
            text-transform: uppercase;
            color: #666;
            margin-top: -15px;
        }

        Setting Up Sale End Dates

        Don’t forget to set your sale end dates in WooCommerce:

        1. Edit your product
        2. Set the sale price
        3. Click the calendar icon next to the sale price
        4. Choose when you want the sale to end

        For variable products, you’ll need to set the sale end date for each variation separately.

        The Alternative Method: Using functions.php (Not Recommended)

        While I strongly recommend using Code Snippets, I know some of you might want to know how to add this code to your functions.php file. So, let’s talk about it – but first, some important warnings!

        What’s a Child Theme and Why It’s Important

        Before thinking about editing functions.php, let’s talk about child themes. A child theme is like a safe playground for your customizations. Here’s why you need one:

        • Never edit your main theme directly: It’s like writing in permanent marker – when the theme updates, all your changes will be erased!
        • Your main theme needs updates: Theme updates often include security fixes and new features. If you modify the main theme, you can’t update without losing your changes.
        • Protection for your customizations: A child theme keeps your custom code separate and safe.

        Think of it this way: Your main theme is like a rental apartment, and a child theme is like putting up removable wallpaper instead of painting the walls. When you move out (change themes), you can take your wallpaper (customizations) with you!

        How to Add Code to functions.php

        If you still want to go this route (remember, Code Snippets is safer!), here’s how:

        1. Create a Child Theme (if you haven’t already):

          • Create a new folder in wp-content/themes/
          • Name it yourtheme-child (replace “yourtheme” with your actual theme name)
          • Create a style.css file with the proper theme headers
          • Create a functions.php file

          2. Add the Code:

            • Open your child theme’s functions.php file
            • Paste the PHP code at the bottom of the file
            • Save the file

            3. Add the CSS:

              • Add the CSS code to your child theme’s style.css file
              • Or use your theme’s custom CSS section in the customizer

              The Big Warning: Theme Changes

              Here’s what happens when you change themes while using functions.php:

              1. All Your Code Disappears: When you switch themes, your countdown timer will stop working immediately.
              2. Manual Transfer Required: You’ll need to copy all your code to your new theme’s child theme.
              3. Potential Conflicts: Your code might not work the same way with the new theme.
              4. Risk of Errors: If you forget to transfer any part of the code, features might break.

              It’s like moving houses and having to reinstall all your light fixtures every time – not fun!

              Why Code Snippets is Better (One More Time!)

              Let me give you one final comparison:

              functions.php Method:

              • ❌ Code disappears when changing themes
              • ❌ Need to create and manage child theme
              • ❌ Risk of breaking your site
              • ❌ Harder to disable if something goes wrong
              • ❌ Need FTP or file manager access
              • ❌ Must copy/paste code when changing themes

              Code Snippets Plugin:

              • ✅ Code stays active with any theme
              • ✅ No child theme needed
              • ✅ Safe and easy to manage
              • ✅ One-click disable if needed
              • ✅ No file editing required
              • ✅ Works right from your dashboard

              Conclusion

              While both methods will get the job done, using Code Snippets is like having a safety net while walking a tightrope. Sure, you could do it without one, but why take the risk?

              Plus, if you ever need to hand over the site to someone else or make quick changes, Code Snippets makes everything so much easier to manage. Trust me, your future self will thank you for choosing the safer, more flexible option!

              Need help setting up a child theme or have questions about Code Snippets? Drop a comment below, and I’ll be happy to help! 🤗

              Need Help?

              If something’s not working quite right:

              • Double-check that both snippets are activated
              • Make sure you’ve set sale end dates for your products
              • Clear your website’s cache if you don’t see the changes immediately

              Happy selling!

              Do you want to thank me and buy me a beer?

              Every donation is entirely welcome but NEVER required. Enjoy my work for free but if you would like to thank me and buy me a beer or two then you can use this form here below.

              Donation Form (#2)

              Here are some of my favorite WordPress tools

              Thanks for reading this article! I hope it's been useful as you work on your own websites and e-commerce sites. I wanted to share some tools I use as a WordPress developer, and I think you'll find them helpful too.

              Just so you know, these are affiliate links. If you decide to use any of them, I'll earn a commission. This helps me create tutorials and YouTube videos. But honestly, I genuinely use and recommend these tools to my friends and family as well. Your support keeps me creating content that benefits everyone.

              Themes: Over the past few years, I've consistently relied on two primary themes for all sorts of projects: the Blocksy theme and the Kadence Theme. If you explore this website and my YouTube channel, you'll come across numerous tutorials that delve into these themes. If you're interested in obtaining a 10% discount for both of these themes, then:

              Code Snippets Manager: WPCodeBox allows you to add code snippets to your site. Not only that, but it also provides you with the capability to construct and oversee your WordPress Code Snippets library right in the cloud. You can grab it with the 20% discount here (SAVE 20% Coupon: WPSH20).

              Contact forms: There are hundreds of contact forms out there but Fluent Forms is the one I like the most. If you need a 20% discount then use this link (save 20% coupon is WPSH20).

              Gutenberg add-ons: If I need a good Gutenberg blocks add-on then Kadence Blocks is the one I have used the most. You’ll get a 10% discount with the coupon SIMPLEHACKS here.

              Website migration: While building a website you probably need a good plugin that can help you with the migration, backups, restoration, and staging sites. Well, WpVivid is the one I have used for the last couple of years. If you use this link along with the WPSH20 coupon you’ll get a 20% discount.

              Woocommerce extensions: There are a bunch of Woocommerce extensions that I like but the one that stands out is Advanced Dynamic Pricing. Once again, you’ll get a 20% discount if you use this link here (save 20% coupon is WPSH20)

              Web Hosting: If you would like to have a really fast and easy-to-use managed cloud hosting, then I recommend Verpex Hosting (see my review here). By the way, this site is hosted in Verpex.)

              To see all my most up-to-date recommendations, check out this resource that I made for you!

              Janek T.
              Janek T.

              Improve this text: {CLIPBOARD}

              - I have been passionate about Wordpress since 2011, creating websites and sharing valuable tips on using Wordpress and Woocommerce on my site.
              - Be the first to receive notifications about new tutorials by subscribing to my Youtube channel .
              - Follow me on Twitter here

              Articles: 127