I hope this is not too specific to WooCommerce.

I have a nifty shortcode that displays a list of all my products with SKUs. However, it also includes products that I have published but have set the catalog visibility to "hidden."

I can't find an argument / parameter to exclude hidden products (or only include those marked as Catalog/Search).

I know it must be simple; I just haven't found it. Thanks for any help.

Here is the code:

$params = array('posts_per_page' => -1, 'post_type' => 'product', 'orderby' => 'menu-order', 'order' => 'asc');
$wc_query = new WP_Query($params);
<table class="product-list tablesorter"><thead><tr><th>SKU</th><th>Product Name</th></tr></thead><tbody>
     <?php if ($wc_query->have_posts()) : ?>
     <?php while ($wc_query->have_posts()) :
                $wc_query->the_post(); ?>
<td><?php global $product; echo $product->get_sku(); ?></td>
<td><a href="<?php the_permalink(); ?>" title="<?php the_title(); ?>"><?php the_title(); ?></a></td>
     <?php endwhile; ?>
     <?php wp_reset_postdata(); ?>
     <?php else:  ?>
          <?php _e( 'No Products' ); ?>
    </td> </tr>
     <?php endif; ?>
  • I would note that this code will eventually fail catastrophically due to the posts_per_page being set to -1. Few servers would handle this code when there are 1000 posts, nevermind 20,000. Multiply that by however many visitors arrive on your site
    – Tom J Nowell
    Commented Dec 3, 2016 at 21:10

2 Answers 2


Important: The following only works for WooCommerce versions less than 3.0. For a more up-to-date answer please see the other answer by kalle.

WooCommerce save this data as metadata so you'll need to run a Meta Query against the name _visibility. Something like:

'meta_query' => array(
        'key'       => '_visibility',
        'value'     => 'hidden',
        'compare'   => '!=',

This will pull all posts that do not have meta _visibility equal to hidden.

  • Perfect. That's what I needed. For anyone who searches for this answer, here is the full query to the above. <?php $params = array('posts_per_page' => -1, 'post_type' => 'product', 'orderby' => 'menu-order', 'order' => 'asc', 'meta_query' => array( array( 'key' => '_visibility', 'value' => 'hidden', 'compare' => '!=', ) )); $wc_query = new WP_Query($params); ?> Commented Jun 30, 2016 at 18:39
  • @PeterIngersoll FYI, you can mark this answer as accepted to show future visitors what worked for you as well :) There's a check mark on the left of Howdy's answer. Read more here: wordpress.stackexchange.com/help/someone-answers
    – Tim Malone
    Commented Jul 5, 2016 at 7:57

As of Woocommerce 3. Visibility is changed to taxonomy instead of meta. So you need to change the meta_query to tax_query. To show only visible products,

'tax_query' => array(
        'taxonomy' => 'product_visibility',
        'field'    => 'name',
        'terms'    => 'exclude-from-catalog',
        'operator' => 'NOT IN',

and examples for Featured Products

'tax_query' => array(
        'taxonomy' => 'product_visibility',
        'field'    => 'name',
        'terms'    => 'featured',

Possible terms: 'exclude-from-search', 'exclude-from-catalog', 'featured', 'outofstock'.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.