// move out of stock products to end of loop in WooCommerce Archives add_action( 'woocommerce_product_query', 'custom_woocommerce_product_query' ); function custom_woocommerce_product_query( $q ) { // Get any existing meta query from the query $meta_query = $q->get('meta_query'); // Add our condition $stock_status_meta_query = array( 'relation' => 'OR', array( 'key' => '_stock_status', 'value' => 'instock', 'compare' => '=', ), array( 'key' => '_stock_status', 'compare' => 'NOT EXISTS', // This ensures compatibility with variations ), ); // If there's already a meta_query, we add ours to it. If not, we create a new one. if (!empty($meta_query)) { $meta_query[] = $stock_status_meta_query; } else { $meta_query = array($stock_status_meta_query); } // Set the modified meta query back $q->set('meta_query', $meta_query); // Order by stock status first $q->set('orderby', array('meta_value' => 'ASC', 'date' => 'DESC')); // This ensures out-of-stock products are listed last $q->set('meta_key', '_stock_status'); $q->set('order', 'ASC'); }