How to Automatically Populate a WooCommerce Sale Category

How to Automatically Populate a WooCommerce Sale Category
On this page
  1. Why an Automatic Sale Category Beats Manual Tagging
  2. Step 1: Create the Sale Category
  3. Step 2: Add the Dynamic Population Snippet
  4. Troubleshooting
  5. Frequently Asked Questions
  6. Conclusion

You can automatically populate a WooCommerce Sale category by creating an empty product category, then hooking into woocommerce_product_query to swap that category’s query for a live list of currently discounted products — no manual tagging of individual products required.

Why an Automatic Sale Category Beats Manual Tagging

  • Manually assigning a “Sale” category to every discounted product is easy to forget and easy to leave stale once a sale ends
  • An automatic version always reflects exactly what’s currently on sale, with zero ongoing maintenance
  • It gives you a real category page (with its own URL, breadcrumb, and navigation menu link) rather than relying solely on a shortcode or block
  • It works for any number of discounted products without per-product effort

Step 1: Create the Sale Category

Go to Products > Categories and add a new category named “Sale” with the slug sale — you don’t need to assign any products to it manually; the snippet below populates it dynamically. If you use a different slug, update the PHP to match.

Step 2: Add the Dynamic Population Snippet

PHP
/** Automatically populate the "sale" category with currently discounted products */
add_action( 'woocommerce_product_query', 'populate_sale_category_dynamically' );

function populate_sale_category_dynamically( $query ) {
    if ( 'sale' !== $query->get( 'product_cat' ) ) {
        return;
    }

    $query->set( 'post_type', 'product' );
    $query->set( 'product_cat', null );

    $on_sale_ids = wc_get_product_ids_on_sale();
    $query->set( 'post__in', $on_sale_ids ? $on_sale_ids : array( 0 ) );
}
Automatically populate a WooCommerce sale category: the page before adding the code
Before
Automatically populate a WooCommerce sale category: the page after adding the code
After

Setting post__in to array( 0 ) when nothing is on sale ensures the query returns zero products cleanly, rather than accidentally matching every product (which happens if post__in is left empty).

Troubleshooting

Category Shows Every Product Instead of Just Sale Items

This typically means the empty-array edge case wasn’t handled — an empty post__in array is ignored by WordPress’s query engine rather than matching nothing, so always fall back to a non-matching placeholder ID like array( 0 ) when there are no sale items.

Layout Looks Different on the Sale Category Page

This snippet only modifies which products the query returns — it doesn’t touch page layout or template selection, so a different appearance points to a separate theme or plugin behavior specific to that category page, not this snippet.

Stopped Working After a WooCommerce Update

Confirm wc_get_product_ids_on_sale() still returns the expected array in your current WooCommerce version by testing it in isolation — occasionally, a store’s specific catalog setup (like scheduled sale prices) can affect what counts as “on sale” at query time.

Frequently Asked Questions

Can shoppers still find the Sale category through search or filters?

Yes — since it’s a real product category with its own URL, it works with navigation menus, breadcrumbs, and any category-based filter widgets exactly like a normal category.

Does this affect the WooCommerce “on sale” shortcode or block?

No — those pull sale products through their own separate query logic; this snippet only affects requests specifically for the “sale” category archive page.

What happens if I rename the category slug later?

The snippet checks for the exact slug sale — renaming the category’s slug without updating the PHP will break the dynamic population, since the query check will no longer match.

Conclusion

A single query filter turns an empty product category into a live, always-accurate feed of discounted products, without any manual tagging or a shortcode-only limitation. Just remember to handle the “nothing currently on sale” edge case explicitly, since an empty query filter can otherwise return every product instead of none. Getting this right is really what automatically populate a woocommerce sale category comes down to.

See also WooCommerce Shop and Category Page Hooks: A Visual Guide. Then read How to Split the WooCommerce Shop Page by Category.

Prefer no code? All-in-One Utilities Woo Add-on adds over 50 WooCommerce features, so you can switch them on without code.

Leave a Reply

Schedule a call