Display sold out on WooCommerce variable product when all variations are out of stock

Rate this post

In WooCommerce I am using the function below where it adds a sold out text on the product thumbnail if the product is out of stock:

add_action( 'woocommerce_before_shop_loop_item_title', 'bbloomer_display_sold_out_loop_woocommerce' );
function bbloomer_display_sold_out_loop_woocommerce() {
    global $product;
    if ( ! $product->is_in_stock() ) {
        echo '<span class="soldout">Sold Out</span>';

It works for a simple product, but not for variable products.

For variable products with variations, if I set all variations to 0 stock quantity except for 1 variation, I notice that the sold out message still appears on the thumbnail. Technically this is not correct as we do have some in stock.

Does anybody know how to change the code below in order to handle this?



You can create a custom conditional function to check if all variations of a variable product are “out of stock” as follows:

function is_variable_product_out_of_stock( $product ) {
    $children_count = 0; // initializing
    $variation_ids  = $product->get_visible_children();
    // Loop through children variations of the parent variable product
    foreach( $variation_ids as $variation_id ) {{
        $variation = wc_get_product($_variation_id); // Get the product variation Object
        if( ! $variation->is_in_stock() ) {
            $children_count++; // count out of stock children
    // Compare counts and return a boolean
    return count($variation_ids) == $children_count ? true : false;

Then you will use it in your revisited hooked function below:

add_action( 'woocommerce_before_shop_loop_item_title', 'display_products_loop_out_of_stock' );
function display_products_loop_out_of_stock() {
    global $product;

    if ( ( ! $product->is_type('variable') && ! $product->is_in_stock()  ) 
    || ( $product->is_type('variable') && is_variable_product_out_of_stock( $product ) ) ) {
        echo '<span class="soldout">Sold Out</span>';

Code goes in functions.php file of the active child theme (or active theme). It should works.

Leave a Reply

Your email address will not be published.

Back to top button