Skip to content

Everything for WordPress, web development — and beyond

How to remove the Add to Cart button in WooCommerce

How to remove the Add to Cart button in WooCommerce

The "Add to cart" button is the fundamental mechanism in WooCommerce that keeps your store running. But fundamental does not mean always appropriate. A showcase site without ordering capability, a custom-order product requiring individual pricing, a sold-out item that should not be unpublished yet: in all these cases the standard Add to Cart just gets in the way.

You could take the blunt approach and set the product status to "hidden," but then it drops out of the catalog and stops being indexed. A much cleaner solution is to keep the product card visible while removing or replacing the purchase button. WooCommerce provides several hooks and filters for this, from global disabling to pinpoint hiding on a single product.

Below are all the working methods, from simple to advanced. Each one has been tested on the current version of WooCommerce.

💡 Quick overview:

  • Entire site at once: two remove_action calls in functions.php, one for the product grid and one for the product page
  • Homepage and archives: conditional woocommerce_is_purchasable filter using is_shop()
  • All categories or one specific category: same filter with is_product_category() or is_product_category('slug')
  • Single product: three methods, built-in admin toggle, zeroing stock, filter by product_id
  • For those who need a button: replace it with custom text or a "Request a quote" button

1. Removing the button from the entire site

If your store functions purely as a showcase with no purchasing intended, the simplest approach is to remove the button globally using two hooks in your active theme's functions.php.

The first hook handles product cards in the grid (the [products] shortcode, shop page, categories), while the second handles individual product pages:

1// Remove button from card grid
2remove_action(
3 'woocommerce_after_shop_loop_item',
4 'woocommerce_template_loop_add_to_cart'
5);
6
7// Remove button from product page
8remove_action(
9 'woocommerce_single_product_summary',
10 'woocommerce_template_single_add_to_cart',
11 30
12);

It is better to place this code not directly in your theme's functions.php (which risks losing changes on update), but through the Code Snippets plugin or a child theme. Before making any edits, create a backup; without one you will have nowhere to roll back.

2. Hiding the button on the homepage and archive pages

Global disabling does not work for everyone. A common scenario: the button should remain on the product page but disappear from the catalog and homepage (where products are displayed as a list).

Here, instead of remove_action, it is better to use the woocommerce_is_purchasable filter with an is_shop() conditional check:

1function ts_hide_cart_on_shop() {
2 if ( is_shop() || is_front_page() ) {
3 add_filter( 'woocommerce_is_purchasable', '__return_false' );
4 }
5}
6add_action( 'wp', 'ts_hide_cart_on_shop' );

The wp hook fires early, before rendering, and avoids repeated checks that would slow down the page. is_shop() covers the main shop page, and is_front_page() covers a static homepage if it displays a WooCommerce shortcode. The filter does not apply to product pages, so purchasing works normally there.

3. Removing the button from all category pages

Same principle, but replace is_shop() with is_product_category() without a parameter. The filter will catch any product category:

1function ts_hide_cart_in_categories() {
2 if ( is_product_category() ) {
3 add_filter( 'woocommerce_is_purchasable', '__return_false' );
4 }
5}
6add_action( 'wp', 'ts_hide_cart_in_categories' );

The button remains on individual product pages. This is useful when the catalog serves as a showcase and purchasing is only available after navigating to the product card, for example, so that users first read the description and specifications.

4. Disabling the button for a single category

Sometimes one category in your store is custom-order while the rest are standard. In that case you need targeted blocking by category slug:

1function ts_hide_cart_for_category() {
2 if ( is_product_category( 'pod-zakaz' ) ) {
3 add_filter( 'woocommerce_is_purchasable', '__return_false' );
4 }
5}
6add_action( 'wp', 'ts_hide_cart_for_category' );

Replace 'pod-zakaz' with the actual slug of your target category. You can find the slug in the admin panel under "Products → Categories" in the "Slug" column. The filter silently disables purchasing for all products in the category; the button will also disappear on the product page because WooCommerce checks is_purchasable() there too.

5. Hiding the button for a specific product

The most common scenario: one product out of hundreds needs to temporarily display without the ability to order. WooCommerce offers three ways to do this.

Method 1: built-in admin toggle

Go to edit the product, open the "Inventory" tab, and switch "Stock status" to "Out of stock." Set the "Allow backorders" checkbox to "Do not allow." Save the product, and the Add to Cart button will disappear automatically.

Configuring product stock status in WooCommerce

This approach requires no code and works out of the box. The downside is that the product gets marked as "Out of stock," which is not always desirable (for example, for digital products or services where "stock" does not make sense).

Method 2: zeroing the stock quantity

In the same "Inventory" tab, uncheck "Manage stock" or set the quantity to 0. The button will disappear when the remaining stock reaches zero.

Zeroing product quantity to hide the purchase button

This method works well for physical products: as soon as the last unit sells, the button disappears on its own. However, like the first method, the product gets an out-of-stock status.

Method 3: filter by product ID

If you need to remove the button without changing the "in stock" status, use a filter that checks the ID:

1function ts_disable_cart_for_product( $purchasable, $product ) {
2 $target_ids = array( 22, 47, 103 ); // Product IDs for which we remove the button
3 if ( in_array( $product->get_id(), $target_ids ) ) {
4 return false;
5 }
6 return $purchasable;
7}
8add_filter( 'woocommerce_is_purchasable', 'ts_disable_cart_for_product', 10, 2 );

Here is what happens: the woocommerce_is_purchasable filter receives the current $purchasable status and the $product object. If $product->get_id() matches one of the IDs in the $target_ids array, it returns false and the button is suppressed. For all other products the original status is returned.

$product->get_id() is the method current since WooCommerce 3.0. The old $product->id property (direct field access) is deprecated and generates notices in the logs; do not use it.

You can expand the $target_ids array as needed. Find the product ID in the admin panel: hover over the product name in the list and the ID will appear in the browser status bar (or open the product and look at the number in the URL: post=22).

6. Replacing the button with custom text

Sometimes you do not need to remove the button; you need to replace it. For example, for custom-order products you might display "Request a quote" with a link to a contact form.

1function ts_replace_cart_button_single( $html, $product ) {
2 $target_ids = array( 22 );
3 if ( in_array( $product->get_id(), $target_ids ) ) {
4 return '<a href="/contact" class="button alt">Request a quote</a>';
5 }
6 return $html;
7}
8add_filter( 'woocommerce_loop_add_to_cart_link', 'ts_replace_cart_button_single', 10, 2 );

This filter intercepts the button HTML before output and replaces it with a custom link using the .button class. It works both for the product grid and for the product page; WooCommerce uses the same filter in both contexts.

For more complex logic (different text for different products, a custom button with a modal window), look into woocommerce_template_single_add_to_cart for a complete button template override via a child theme.

⁉️🤔 Frequently asked questions

Is it safe to edit functions.php directly?

Without experience, no. functions.php executes on every request, and a syntax error in it brings down the entire site (white screen). Use the Code Snippets plugin, which provides an interface for adding PHP fragments with syntax checking and automatic disabling on fatal errors. Alternatively, edit via FTP/SFTP after saving a working copy of the file locally.

How do I hide the button only for logged-out users?

Add an is_user_logged_in() check to any of the conditions above. For example: if ( ! is_user_logged_in() && is_shop() ) { add_filter(...); }. Guests see a showcase without buttons; registered users get full functionality. This is a common use case for wholesale stores where prices and the cart only become available after login.

The button disappeared but the price and variations remained; is this normal?

Yes. The remove_action hooks and the woocommerce_is_purchasable filter remove only the add-to-cart button. The price and variation selectors (color, size) remain visually. If you need to hide those as well, add CSS: .single-product .variations_form, .single-product .price { display: none; }, or use a deeper intervention via woocommerce_get_price_html.

After a theme update all my changes were lost; how do I protect against this?

Never make changes directly in the parent theme's functions.php. Any theme update will overwrite the file. Three reliable options: a child theme (with its own functions.php), the Code Snippets plugin (snippets live in the database and survive updates), or a simple MU-plugin (/wp-content/mu-plugins/disable-cart.php, which cannot be disabled from the admin panel and is not affected by updates).

Can I restore the button for a specific product after a global disable?

Yes. After the woocommerce_is_purchasable filter globally returns __return_false, add a second filter with a higher priority that returns true for the needed IDs: add_filter( 'woocommerce_is_purchasable', 'ts_enable_for_specific', 20, 2 );. Priority 20 executes after 10 and can override the return value.

Which method to choose for your task

If you are building a showcase without online payments, use the global disable with two remove_action calls. Need to block purchases in the catalog but keep them in product cards? Use the filter with is_shop(). One problematic category? Use is_product_category('slug'). One product out of hundreds? Use the built-in stock settings or the filter by ID.

And most importantly: before changing anything in functions.php, make a backup. Not through a plugin you are about to edit, but a full backup via your hosting or UpdraftPlus. Five minutes spent on a backup saves hours of recovery.