You can hide products by custom field value in WooCommerce by adding a meta query condition to the shop page’s product query with woocommerce_product_query, excluding any product whose custom field (or ACF field) matches a specific key/value pair.
Why Hide Products Based on a Custom Field
- You use a custom field or ACF value to flag products as “internal only,” “discontinued,” or “pending review”
- Marking products this way is faster for staff than changing catalog visibility settings one by one
- You need conditional hiding logic that doesn’t fit WooCommerce’s built-in category or tag-based visibility rules
Step 1: Exclude Matching Products From the Shop Query
/** Hide any product where custom field "internal_only" equals "yes" */
add_action( 'woocommerce_product_query', 'exclude_internal_only_products', 9999, 2 );
function exclude_internal_only_products( $q, $query ) {
if ( is_admin() ) return;
$meta_query = $q->get( 'meta_query' );
$meta_query[] = array(
'relation' => 'OR',
array(
'key' => 'internal_only',
'compare' => 'NOT EXISTS',
),
array(
'key' => 'internal_only',
'value' => 'yes',
'compare' => '!=',
),
);
$q->set( 'meta_query', $meta_query );
}

Swap internal_only and yes for your actual custom field key and the value that should trigger hiding.
Troubleshooting
Products Still Appear on the Shop Page
Confirm the key/value pair matches exactly what’s saved — ACF sometimes stores values with different casing or as serialized arrays for certain field types (like checkboxes), which won’t match a simple string comparison.
Products Disappear From Search or Category Pages Too
This is expected — woocommerce_product_query affects the shop, category, and any WooCommerce product loop by default. If you want it limited to only the main shop page, add an is_shop() check inside the callback.
Frequently Asked Questions
Does this remove the product entirely, or just hide it from listings?
It only removes the product from query results (shop, category, search) — the product page itself remains accessible by direct URL unless you add separate logic to block that too.
Can I hide products based on more than one field?
Yes, add additional conditions to the $meta_query array, adjusting the relation as needed for AND/OR logic across multiple fields.
Will this work with ACF Pro’s repeater or select fields?
For simple text/select fields, yes. Repeater and complex field types often need a modified compare operator (like LIKE) since their stored values aren’t plain strings.
Conclusion
Hiding products by custom field value in WooCommerce is a flexible technique built on the woocommerce_product_query hook and a meta query condition. It works well alongside ACF or any plugin that stores product-level custom fields.
See also How to Show a Product Custom Field on WooCommerce Category Pages. Then read How to Display a Product ACF Value on the WooCommerce Shop Page.
Prefer no code? All-in-One Utilities Woo Add-on adds over 50 WooCommerce features, so you can switch them on without code.