Posted on

Hidden WooCommerce products in search

Relevanssi by default shows hidden WooCommerce products in the search results. It is quite easy to make Relevanssi not to display hidden products in the results. The best way is to unindex the products, so that they don’t appear in the index at all.

How that is done, depends on the version of WooCommerce you’re using.

WooCommerce 3

WooCommerce 3 uses taxonomy terms to handle the visibility.

add_filter('relevanssi_do_not_index', 'rlv_wc3_hidden_filter', 10, 2);
function rlv_wc3_hidden_filter($block, $post_id) {
  if (has_term('exclude-from-catalog', 'product_visibility', $post_id)) $block = true;
  if (has_term('exclude-from-search', 'product_visibility', $post_id)) $block = true;
  if (has_term('outofstock', 'product_visibility', $post_id)) $block = true;
  return $block;

This code, placed in the theme functions.php, will unindex products that set to be excluded from the catalog, excluded from search or that are out of stock. If you want to keep out of stock items in the search results, just remove that line from the function.

The changes take effect once you rebuild the index. Do note that if you change the product visibility without saving the post, the changes won’t be reflected in the index until the post is saved or the index is otherwise rebuilt.

WooCommerce 2

Earlier versions of WooCommerce use a custom field to control the visibility.

add_filter('relevanssi_do_not_index', 'rlv_wc2_hidden_filter', 10, 2);
function rlv_wc2_hidden_filter($block, $post_id) {
  $visibility = get_post_meta($post_id, '_visibility', true);
  if ("catalog" == $visibility) $block = true;
  if ("hidden" == $visibility) $block = true;
  return $block;

The visibility setting has four values: “visible”, “catalog”, “search” and “hidden”. “Visible” means it’s visible everywhere, “hidden” means it’s hidden everywhere. “Catalog” means the product is visible in shop pages and category pages, but not search results. “Search” means the product is visible in search results, but not in the shop page or category pages. This function matches that definition.

Again, you need to rebuild the index to see the effects from this.

  • Cody Henderson

    This code snippet is causing my index building to fail. The indexing process begins to index less than the specified amount of documents, until it locks up altogether, with a little more than half the documents indexed.

    As soon as I remove this code from my functions.php, I can continue to build the index again. Any ideas?

    • Reduce the number of posts to index, then. This adds a new database three extra database queries per post, which can slow down – especially if it’s a slow query.

      There’s probably a faster way to do this, perhaps it’s possible to fetch a list of all excluded posts at once and then check against that list.

  • Mae

    Hello. I’ve coped and pasted your code and added to functions.php. Then I rebuild the index. All of my products that are “hidden” are still showing in the search. I’m using the latest woocommerce version. Thank-you.

    • If you add

      var_dump(has_term(‘exclude-from-search’, ‘product_visibility’, $post_id)); exit();

      before the “return $block;” line in the function and go save a hidden post, what does it print out?

      • Mae

        Hi. Thanks for your response. I have done this, but where do I find the dump?

        • It should print it out immediately once you save a hidden post. Are you sure you have Relevanssi enabled and active?

          • Mae

            Yes, absolutely. I have a product that is marked as “hidden” for catalog visibility. Relevanssi is active (other changes I’ve made in relevanssi are active). I have the code with the var_dump before the return $block. I go to a “hidden” product and re-save it. I don’t see anything. Here’s the code:

            add_filter(‘relevanssi_do_not_index’, ‘rlv_wc3_hidden_filter’, 10, 2);
            function rlv_wc3_hidden_filter($block, $post_id) {
            if (has_term(‘exclude-from-catalog’, ‘product_visibility’, $post_id)) $block = true;
            if (has_term(‘exclude-from-search’, ‘product_visibility’, $post_id)) $block = true;
            if (has_term(‘outofstock’, ‘product_visibility’, $post_id)) $block = true;
            var_dump(has_term(‘exclude-from-search’, ‘product_visibility’, $post_id)); exit();
            return $block;

          • There’s an exit(); in the code, so it should simply halt the process. If that doesn’t happen when you save a post, then the code is not running at all. This filter should trigger every time you save a post. Does it trigger when you save a product that is not hidden from Relevanssi? Or another post type?

          • Mae

            No, it does not trigger at all when saving a non-hidden product or any other post types. Do you think I have a plugin or other code in functions.php that is stopping this? Heartbeat control???

          • And you’re 100% sure that Relevanssi is set to index posts? This filter should trigger each and every time a post is indexed. If Relevanssi is working, then I’d look at making sure this filter is somewhere that is being run. You’re sure it’s in the right file?

          • Mae

            total rookie mistake, I didn’t close my comment in functions.php properly. The code works fine. Thanks so much for your support. I will plan to buy the premium version and leave a positive comment on wordpress. Thank-you.