How to Add Catalog Mode to Your WooCommerce Store (The Easy Way)

Ever wanted to show your products without letting people buy them right away? Maybe you run a wholesale business, or you want to show prices only to logged-in customers? Well, I’ve got just the solution for you – a nifty catalog mode feature for WooCommerce that I’ve been using for years.

What Does Woocommerce Catalog Mode Do?

This piece of code turns your WooCommerce store into a window-shopping paradise. Here’s what you can do with it:

  • Hide prices and “Add to Cart” buttons for everyone or just specific users
  • Show prices but hide the “Add to Cart” button (great for “contact us to order” scenarios)
  • Control visibility based on whether users are logged in or not
  • Set different rules for specific user roles (like wholesale customers)
  • Apply catalog mode to specific product categories
  • Control settings globally or per individual product

Why Would You Want This?

There are tons of reasons why you might want to use catalog mode:

  • Running a B2B store where you want casual visitors to browse but only registered businesses to see prices
  • Selling custom products where prices vary based on specifications
  • Creating a product showcase without enabling direct purchases
  • Setting up a members-only pricing system
  • Temporarily disabling purchases while updating prices

Video: How to Add Catalog Mode to Your WooCommerce Store?

How to Implement the Catalogue Mode?

Now, you’ve got two ways to add this to your site. Let me share the better option first:

Option 1: Using WPCode Lite (Recommended)

  1. Install and activate the free WPCode Lite plugin from WordPress repository
  2. Go to Code Snippets → Add New
  3. Give your snippet a name (like “WooCommerce Catalog Mode”)
  4. Choose “php snippet” as the code type
  5. Paste the entire code into the code editor
  6. Set the snippet to “Active” and save

Why is this the better way?

  • If you make a mistake, your site won’t break
  • You can easily disable the feature if needed
  • Your code won’t disappear when you change themes
  • You can manage multiple custom code snippets in one place

Option 2: Using functions.php

You could add this to your theme’s functions.php file, but I really don’t recommend it. If you still want to go this route:

  1. Back up your site first (seriously, do it!)
  2. Go to Appearance → Theme Editor
  3. Open functions.php
  4. Add the code at the end of the file
  5. Save and pray nothing breaks

Setting It Up

Once you’ve added the code, you’ll find a new “Catalog Mode” menu item under WooCommerce in your WordPress admin. Here you can:

  1. Enable catalog mode globally
  2. Choose whether to hide prices on archive pages only
  3. Set up rules for logged-in vs logged-out users
  4. Select specific user roles
  5. Choose product categories

Plus, when editing individual products, you’ll find a new “Catalog Mode” tab in the product data box where you can override these settings for specific products.

The Code Snippet for you

if (!defined('ABSPATH')) {
    exit; // Exit if accessed directly
}

/*------------------------------------------------------------------------------
  ADMIN SCRIPTS & AJAX HANDLER
------------------------------------------------------------------------------*/

/**
 * Enqueue Select2 on the global Catalog Mode settings page
 */
add_action('admin_enqueue_scripts', 'catalog_mode_admin_scripts');
function catalog_mode_admin_scripts($hook) {
    // Load scripts only on our Catalog Mode settings page
    if ('woocommerce_page_catalog_mode_settings' !== $hook) {
        return;
    }
    // Enqueue Select2 assets
    wp_enqueue_style('select2css', 'https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css', array(), '4.1.0');
    wp_enqueue_script('select2js', 'https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js', array('jquery'), '4.1.0', true);

    // Initialize Select2 for our global fields and add "Select All" click handlers
    wp_add_inline_script(
        'select2js',
        'jQuery(document).ready(function($){
            // Global roles field
            $(".wc-catalog-mode-roles, .wc-hide-atc-roles").select2({
                width: "300px"
            });
            // Global categories field using AJAX
            $(".wc-catalog-mode-categories-ajax").select2({
                width: "300px",
                ajax: {
                    url: ajaxurl,
                    dataType: "json",
                    delay: 250,
                    data: function(params) {
                        return {
                            q: params.term,
                            action: "ajax_get_product_categories"
                        };
                    },
                    processResults: function(data) {
                        return { results: data };
                    },
                    cache: true
                },
                placeholder: "Search for categories",
                minimumInputLength: 1
            });
            // "Select All" for roles
            $(".select-all-roles").on("click", function(e) {
                e.preventDefault();
                var select = $(this).siblings("select");
                select.find("option").prop("selected", true);
                select.trigger("change");
            });
            // "Select All" for categories
            $(".select-all-categories").on("click", function(e) {
                e.preventDefault();
                // For AJAX select2, we cannot load all options.
                // Instead, we can inform the admin to use the search box.
                alert("Due to the large number of categories, please use the search box to select categories.");
            });
        });'
    );
}

/**
 * Enqueue Select2 on single product edit pages
 */
add_action('admin_enqueue_scripts', 'catalog_mode_product_admin_scripts');
function catalog_mode_product_admin_scripts($hook) {
    global $post;
    // Only load on product edit pages (post.php or post-new.php) for 'product' post type
    if (( 'post.php' === $hook || 'post-new.php' === $hook ) && isset($post->post_type) && 'product' === $post->post_type ) {
        // Enqueue Select2 assets
        wp_enqueue_style('select2css', 'https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/css/select2.min.css', array(), '4.1.0');
        wp_enqueue_script('select2js', 'https://cdn.jsdelivr.net/npm/select2@4.1.0-rc.0/dist/js/select2.min.js', array('jquery'), '4.1.0', true);

        // Initialize Select2 for product-level fields and add "Select All" handler
        wp_add_inline_script(
            'select2js',
            'jQuery(document).ready(function($){
                $(".wc-hide-atc-product-roles").select2({
                    width: "300px"
                });
                $(".select-all-product-roles").on("click", function(e) {
                    e.preventDefault();
                    var select = $(this).siblings("select");
                    select.find("option").prop("selected", true);
                    select.trigger("change");
                });
            });'
        );
    }
}

/**
 * AJAX handler for fetching product categories with caching.
 */
add_action('wp_ajax_ajax_get_product_categories', 'ajax_get_product_categories');
function ajax_get_product_categories() {
    if (!current_user_can('manage_woocommerce')) {
        wp_send_json_error();
    }
    $search = isset($_GET['q']) ? sanitize_text_field($_GET['q']) : '';
    $cache_key = 'ajax_product_categories_' . md5($search);
    $results = get_transient($cache_key);
    if ($results === false) {
        $terms = get_terms(array(
            'taxonomy'   => 'product_cat',
            'hide_empty' => false,
            'search'     => $search,
            'number'     => 20,
        ));
        $results = array();
        if (!is_wp_error($terms)) {
            foreach ($terms as $term) {
                $results[] = array('id' => $term->term_id, 'text' => $term->name);
            }
        }
        set_transient($cache_key, $results, HOUR_IN_SECONDS);
    }
    wp_send_json($results);
}

/*------------------------------------------------------------------------------
  ADMIN MENU & SETTINGS PAGE
------------------------------------------------------------------------------*/
add_action('admin_menu', 'add_catalog_mode_menu');
function add_catalog_mode_menu() {
    add_submenu_page(
        'woocommerce',
        __('Catalog Mode', 'woocommerce'),
        __('Catalog Mode', 'woocommerce'),
        'manage_woocommerce',
        'catalog_mode_settings',
        'catalog_mode_settings_page'
    );
}

function catalog_mode_settings_page() {
    ?>
    <div class="wrap">
        <h1><?php _e('Catalog Mode Settings', 'woocommerce'); ?></h1>
        <form method="post" action="options.php">
            <?php
            settings_fields('catalog_mode_options_group');
            do_settings_sections('catalog_mode_settings');
            submit_button();
            ?>
        </form>
    </div>
    <?php
}

/*------------------------------------------------------------------------------
  REGISTER SETTINGS
------------------------------------------------------------------------------*/
add_action('admin_init', 'register_catalog_mode_settings');
function register_catalog_mode_settings() {
    // Global Catalog Mode (hide price & Add to Cart)
    register_setting('catalog_mode_options_group', 'wc_catalog_mode_enabled');
    register_setting('catalog_mode_options_group', 'wc_catalog_mode_archive_only');
    register_setting('catalog_mode_options_group', 'wc_catalog_mode_single_only');
    register_setting('catalog_mode_options_group', 'wc_catalog_mode_logged_in_only');
    register_setting('catalog_mode_options_group', 'wc_catalog_mode_logged_out_only');
    register_setting('catalog_mode_options_group', 'wc_catalog_mode_user_roles', array(
        'type'              => 'array',
        'sanitize_callback' => 'sanitize_array',
    ));
    register_setting('catalog_mode_options_group', 'wc_catalog_mode_categories', array(
        'type'              => 'array',
        'sanitize_callback' => 'sanitize_array',
    ));

    // Hide Add to Cart only (prices remain visible)
    register_setting('catalog_mode_options_group', 'wc_hide_add_to_cart_button');
    register_setting('catalog_mode_options_group', 'wc_hide_add_to_cart_button_logged_in');
    register_setting('catalog_mode_options_group', 'wc_hide_add_to_cart_button_logged_out');
    register_setting('catalog_mode_options_group', 'wc_hide_add_to_cart_button_user_roles', array(
        'type'              => 'array',
        'sanitize_callback' => 'sanitize_array',
    ));

    // Main section
    add_settings_section(
        'catalog_mode_options',
        __('Catalog Mode Options', 'woocommerce'),
        'catalog_mode_section_text',
        'catalog_mode_settings'
    );

    // Global Catalog Mode fields
    add_settings_field(
        'wc_catalog_mode_enabled',
        __('Enable Catalog Mode', 'woocommerce'),
        'catalog_mode_enabled_input',
        'catalog_mode_settings',
        'catalog_mode_options'
    );
    add_settings_field(
        'wc_catalog_mode_archive_only',
        __('Hide prices and "Add to Cart" on archive pages', 'woocommerce'),
        'catalog_mode_archive_only_input',
        'catalog_mode_settings',
        'catalog_mode_options'
    );
    add_settings_field(
        'wc_catalog_mode_logged_in_only',
        __('Activate catalog mode for logged-in users', 'woocommerce'),
        'catalog_mode_logged_in_only_input',
        'catalog_mode_settings',
        'catalog_mode_options'
    );
    add_settings_field(
        'wc_catalog_mode_logged_out_only',
        __('Activate catalog mode for logged-out users', 'woocommerce'),
        'catalog_mode_logged_out_only_input',
        'catalog_mode_settings',
        'catalog_mode_options'
    );
    add_settings_field(
        'wc_catalog_mode_user_roles',
        __('Activate catalog mode for specific user roles', 'woocommerce'),
        'catalog_mode_user_roles_input',
        'catalog_mode_settings',
        'catalog_mode_options'
    );
    add_settings_field(
        'wc_catalog_mode_categories',
        __('Activate catalog mode for specific product categories', 'woocommerce'),
        'catalog_mode_categories_input',
        'catalog_mode_settings',
        'catalog_mode_options'
    );

    // Section heading for Hide Add to Cart options
    add_settings_section(
        'hide_add_to_cart_options',
        __('Hide Add to cart options', 'woocommerce'),
        '__return_false',
        'catalog_mode_settings'
    );

    // Hide Add to Cart only fields
    add_settings_field(
        'wc_hide_add_to_cart_button',
        __('Hide add to cart button globally', 'woocommerce'),
        'hide_add_to_cart_button_global_input',
        'catalog_mode_settings',
        'hide_add_to_cart_options'
    );
    add_settings_field(
        'wc_catalog_mode_single_only',
        __('Hide "Add to Cart" on single product pages', 'woocommerce'),
        'catalog_mode_single_only_input',
        'catalog_mode_settings',
        'hide_add_to_cart_options'
    );
    add_settings_field(
        'wc_hide_add_to_cart_button_logged_in',
        __('Hide add to cart button for logged in users', 'woocommerce'),
        'hide_add_to_cart_button_logged_in_input',
        'catalog_mode_settings',
        'hide_add_to_cart_options'
    );
    add_settings_field(
        'wc_hide_add_to_cart_button_logged_out',
        __('Hide add to cart button for logged out users', 'woocommerce'),
        'hide_add_to_cart_button_logged_out_input',
        'catalog_mode_settings',
        'hide_add_to_cart_options'
    );
    add_settings_field(
        'wc_hide_add_to_cart_button_user_roles',
        __('Hide add to cart button for specific user roles', 'woocommerce'),
        'hide_add_to_cart_button_user_roles_input',
        'catalog_mode_settings',
        'hide_add_to_cart_options'
    );
}

/*------------------------------------------------------------------------------
  SECTION TEXT
------------------------------------------------------------------------------*/
function catalog_mode_section_text() {
    echo '<p>' . __('Configure the Catalog Mode settings for your store.', 'woocommerce') . '</p>';
}

/*------------------------------------------------------------------------------
  INPUT FIELDS FOR GLOBAL SETTINGS
------------------------------------------------------------------------------*/
// Catalog Mode checkboxes
function catalog_mode_enabled_input() {
    $enabled = get_option('wc_catalog_mode_enabled', 'no');
    echo '<input type="checkbox" name="wc_catalog_mode_enabled" value="yes" ' . checked($enabled, 'yes', false) . ' />';
    echo '<p class="description">Hide prices and Add to Cart buttons site-wide.</p>';
}
function catalog_mode_archive_only_input() {
    $archive_only = get_option('wc_catalog_mode_archive_only', 'no');
    echo '<input type="checkbox" name="wc_catalog_mode_archive_only" value="yes" ' . checked($archive_only, 'yes', false) . ' />';
    echo '<p class="description">Hide on archive pages only.</p>';
}
function catalog_mode_single_only_input() {
    $single_only = get_option('wc_catalog_mode_single_only', 'no');
    echo '<input type="checkbox" name="wc_catalog_mode_single_only" value="yes" ' . checked($single_only, 'yes', false) . ' />';
    echo '<p class="description">Hide Add to Cart on single product pages only.</p>';
}
function catalog_mode_logged_in_only_input() {
    $logged_in_only = get_option('wc_catalog_mode_logged_in_only', 'no');
    echo '<input type="checkbox" name="wc_catalog_mode_logged_in_only" value="yes" ' . checked($logged_in_only, 'yes', false) . ' />';
    echo '<p class="description">Activate catalog mode for logged-in users.</p>';
}
function catalog_mode_logged_out_only_input() {
    $logged_out_only = get_option('wc_catalog_mode_logged_out_only', 'no');
    echo '<input type="checkbox" name="wc_catalog_mode_logged_out_only" value="yes" ' . checked($logged_out_only, 'yes', false) . ' />';
    echo '<p class="description">Activate catalog mode for logged-out users.</p>';
}

// Global User Roles (Select2 multi-select with "Select All" button)
function catalog_mode_user_roles_input() {
    $selected_roles = get_option('wc_catalog_mode_user_roles', array());
    $roles = get_editable_roles();
    echo '<select name="wc_catalog_mode_user_roles[]" class="wc-catalog-mode-roles" multiple="multiple" style="width:300px;">';
    foreach ($roles as $role => $details) {
        $selected = in_array($role, $selected_roles) ? 'selected="selected"' : '';
        echo '<option value="' . esc_attr($role) . '" ' . $selected . '>' . esc_html($details['name']) . '</option>';
    }
    echo '</select>';
    echo '<button type="button" class="select-all-roles button">' . __('Select All', 'woocommerce') . '</button>';
    echo '<p class="description">Select user roles for which catalog mode should be activated.</p>';
}

// Global Categories (AJAX-based, with "Select All" button)
function catalog_mode_categories_input() {
    $selected_cats = get_option('wc_catalog_mode_categories', array());
    $preloaded_options = '';
    if (!empty($selected_cats)) {
        $terms = get_terms(array(
            'taxonomy'   => 'product_cat',
            'hide_empty' => false,
            'include'    => $selected_cats,
        ));
        if (!is_wp_error($terms)) {
            foreach ($terms as $term) {
                $preloaded_options .= '<option value="' . esc_attr($term->term_id) . '" selected="selected">' . esc_html($term->name) . '</option>';
            }
        }
    }
    echo '<select name="wc_catalog_mode_categories[]" class="wc-catalog-mode-categories-ajax" multiple="multiple" style="width:300px;">';
    echo $preloaded_options;
    echo '</select>';
    echo '<button type="button" class="select-all-categories button">' . __('Select All', 'woocommerce') . '</button>';
    echo '<p class="description">Select product categories for which catalog mode should be activated.</p>';
}

// Hide Add to Cart only fields
function hide_add_to_cart_button_global_input() {
    $value = get_option('wc_hide_add_to_cart_button', 'no');
    echo '<input type="checkbox" name="wc_hide_add_to_cart_button" value="yes" ' . checked($value, 'yes', false) . ' />';
    echo '<p class="description">Hide the Add to Cart button for every product.</p>';
}
function hide_add_to_cart_button_logged_in_input() {
    $value = get_option('wc_hide_add_to_cart_button_logged_in', 'no');
    echo '<input type="checkbox" name="wc_hide_add_to_cart_button_logged_in" value="yes" ' . checked($value, 'yes', false) . ' />';
    echo '<p class="description">Hide the Add to Cart button for logged in users.</p>';
}
function hide_add_to_cart_button_logged_out_input() {
    $value = get_option('wc_hide_add_to_cart_button_logged_out', 'no');
    echo '<input type="checkbox" name="wc_hide_add_to_cart_button_logged_out" value="yes" ' . checked($value, 'yes', false) . ' />';
    echo '<p class="description">Hide the Add to Cart button for logged out users.</p>';
}
function hide_add_to_cart_button_user_roles_input() {
    $selected_roles = get_option('wc_hide_add_to_cart_button_user_roles', array());
    $roles = get_editable_roles();
    echo '<select name="wc_hide_add_to_cart_button_user_roles[]" class="wc-hide-atc-roles" multiple="multiple" style="width:300px;">';
    foreach ($roles as $role => $details) {
        $selected = in_array($role, $selected_roles) ? 'selected="selected"' : '';
        echo '<option value="' . esc_attr($role) . '" ' . $selected . '>' . esc_html($details['name']) . '</option>';
    }
    echo '</select>';
    echo '<button type="button" class="select-all-roles button">' . __('Select All', 'woocommerce') . '</button>';
}

/*------------------------------------------------------------------------------
  SANITIZE ARRAY
------------------------------------------------------------------------------*/
function sanitize_array($input) {
    return is_array($input) ? array_map('sanitize_text_field', $input) : array();
}

/*------------------------------------------------------------------------------
  HELPER FUNCTIONS FOR FRONT-END CONDITIONS
------------------------------------------------------------------------------*/
function should_hide_price($product) {
    // Global catalog mode conditions
    $global_catalog      = get_option('wc_catalog_mode_enabled') === 'yes';
    $archive_only        = get_option('wc_catalog_mode_archive_only') === 'yes' && is_archive();
    $global_logged_in    = get_option('wc_catalog_mode_logged_in_only') === 'yes' && is_user_logged_in();
    $global_logged_out   = get_option('wc_catalog_mode_logged_out_only') === 'yes' && !is_user_logged_in();
    $global_roles        = get_option('wc_catalog_mode_user_roles', array());
    $user_roles          = wp_get_current_user()->roles;
    $role_check          = !empty(array_intersect($user_roles, $global_roles));
    $global_categories   = get_option('wc_catalog_mode_categories', array());
    $product_categories  = wp_get_post_terms($product->get_id(), 'product_cat', array('fields' => 'ids'));
    $category_check      = !empty(array_intersect($product_categories, $global_categories));

    // Per-product settings
    $product_catalog         = get_post_meta($product->get_id(), '_catalog_mode_enabled', true) === 'yes';
    $product_logged_in_only  = get_post_meta($product->get_id(), '_catalog_mode_logged_in_only', true) === 'yes' && is_user_logged_in();
    $product_logged_out_only = get_post_meta($product->get_id(), '_catalog_mode_logged_out_only', true) === 'yes' && !is_user_logged_in();

    return ($global_catalog || $archive_only || $global_logged_in || $global_logged_out || $role_check || $category_check || $product_catalog || $product_logged_in_only || $product_logged_out_only);
}

function should_hide_add_to_cart($product) {
    // Global catalog mode conditions (hide both price and ATC)
    $global_catalog      = get_option('wc_catalog_mode_enabled') === 'yes';
    $archive_only        = get_option('wc_catalog_mode_archive_only') === 'yes' && is_archive();
    $single_only         = get_option('wc_catalog_mode_single_only') === 'yes' && is_product();
    $global_logged_in    = get_option('wc_catalog_mode_logged_in_only') === 'yes' && is_user_logged_in();
    $global_logged_out   = get_option('wc_catalog_mode_logged_out_only') === 'yes' && !is_user_logged_in();
    $global_roles        = get_option('wc_catalog_mode_user_roles', array());
    $user_roles          = wp_get_current_user()->roles;
    $role_check          = !empty(array_intersect($user_roles, $global_roles));
    $global_categories   = get_option('wc_catalog_mode_categories', array());
    $product_categories  = wp_get_post_terms($product->get_id(), 'product_cat', array('fields' => 'ids'));
    $category_check      = !empty(array_intersect($product_categories, $global_categories));

    // Per-product catalog mode
    $product_catalog         = get_post_meta($product->get_id(), '_catalog_mode_enabled', true) === 'yes';
    $product_logged_in_only  = get_post_meta($product->get_id(), '_catalog_mode_logged_in_only', true) === 'yes' && is_user_logged_in();
    $product_logged_out_only = get_post_meta($product->get_id(), '_catalog_mode_logged_out_only', true) === 'yes' && !is_user_logged_in();

    // Global hide-ATC-only options
    $global_hide_atc           = get_option('wc_hide_add_to_cart_button') === 'yes';
    $global_hide_atc_logged_in = get_option('wc_hide_add_to_cart_button_logged_in') === 'yes' && is_user_logged_in();
    $global_hide_atc_logged_out= get_option('wc_hide_add_to_cart_button_logged_out') === 'yes' && !is_user_logged_in();
    $global_hide_atc_roles     = get_option('wc_hide_add_to_cart_button_user_roles', array());
    $hide_role_check           = !empty(array_intersect($user_roles, $global_hide_atc_roles));

    // Per-product hide-ATC only
    $product_hide_atc          = get_post_meta($product->get_id(), '_hide_add_to_cart_button', true) === 'yes';
    $product_hide_atc_logged_in  = get_post_meta($product->get_id(), '_hide_atc_logged_in', true) === 'yes' && is_user_logged_in();
    $product_hide_atc_logged_out = get_post_meta($product->get_id(), '_hide_atc_logged_out', true) === 'yes' && !is_user_logged_in();
    $product_hide_atc_roles      = (array) get_post_meta($product->get_id(), '_hide_add_to_cart_button_user_roles', true);
    $hide_atc_role_check         = !empty(array_intersect($user_roles, $product_hide_atc_roles));

    return (
        $global_catalog || $archive_only || $single_only ||
        $global_logged_in || $global_logged_out ||
        $role_check || $category_check ||
        $product_catalog || $product_logged_in_only || $product_logged_out_only ||
        $global_hide_atc || $global_hide_atc_logged_in || $global_hide_atc_logged_out ||
        $hide_role_check || $product_hide_atc ||
        $product_hide_atc_logged_in || $product_hide_atc_logged_out ||
        $hide_atc_role_check
    );
}

/*------------------------------------------------------------------------------
  FRONT-END LOGIC
------------------------------------------------------------------------------*/
// Hide prices
add_filter('woocommerce_get_price_html', 'hide_price_if_catalog_mode', 10, 2);
function hide_price_if_catalog_mode($price, $product) {
    if (should_hide_price($product)) {
        return '';
    }
    return $price;
}

// Hide Add to Cart for simple/variable products
add_filter('woocommerce_is_purchasable', 'hide_add_to_cart_if_catalog_mode', 10, 2);
function hide_add_to_cart_if_catalog_mode($purchasable, $product) {
    if (should_hide_add_to_cart($product)) {
        return false;
    }
    return $purchasable;
}

// Remove Add to Cart form for variable products on single pages
add_action('wp', 'remove_add_to_cart_for_catalog_mode');
function remove_add_to_cart_for_catalog_mode() {
    if (is_product()) {
        global $product;
        if (!$product) {
            return;
        }
        if (should_hide_add_to_cart($product)) {
            remove_action('woocommerce_single_product_summary', 'woocommerce_template_single_add_to_cart', 30);
        }
    }
}

/*------------------------------------------------------------------------------
  PRODUCT EDITING (ADMIN) FIELDS
------------------------------------------------------------------------------*/
add_filter('woocommerce_product_data_tabs', 'add_catalog_mode_product_tab');
function add_catalog_mode_product_tab($tabs) {
    $tabs['catalog_mode'] = array(
        'label'    => __('Catalog Mode', 'woocommerce'),
        'target'   => 'catalog_mode_product_data',
        'class'    => array(),
        'priority' => 100,
    );
    return $tabs;
}

add_action('woocommerce_product_data_panels', 'add_catalog_mode_product_fields');
function add_catalog_mode_product_fields() {
    ?>
    <div id="catalog_mode_product_data" class="panel woocommerce_options_panel">
        <div class="options_group">
            <?php
            // Existing product-level Catalog Mode fields
            woocommerce_wp_checkbox(array(
                'id'          => '_catalog_mode_enabled',
                'label'       => __('Activate Catalog Mode', 'woocommerce'),
                'description' => __('Hide price and Add to Cart for this product.', 'woocommerce'),
            ));
            woocommerce_wp_checkbox(array(
                'id'          => '_catalog_mode_logged_in_only',
                'label'       => __('Activate catalog mode only for logged-in users', 'woocommerce'),
                'description' => __('Hide price and Add to Cart only for logged-in users.', 'woocommerce'),
            ));
            woocommerce_wp_checkbox(array(
                'id'          => '_catalog_mode_logged_out_only',
                'label'       => __('Activate catalog mode only for logged-out users', 'woocommerce'),
                'description' => __('Hide price and Add to Cart only for logged-out users.', 'woocommerce'),
            ));
            woocommerce_wp_checkbox(array(
                'id'          => '_hide_add_to_cart_button',
                'label'       => __('Hide Add to Cart button', 'woocommerce'),
                'description' => __('Hide only the Add to Cart button (price remains visible).', 'woocommerce'),
            ));
            ?>
        </div>

        <!-- New fields for Hide Add to Cart (logged in, logged out, specific roles) -->
        <div class="options_group">
            <?php
            woocommerce_wp_checkbox(array(
                'id'          => '_hide_atc_logged_in',
                'label'       => __('Hide "Add to Cart" for logged-in users', 'woocommerce'),
                'description' => __('Hide only the Add to Cart button for logged-in users.', 'woocommerce'),
            ));
            woocommerce_wp_checkbox(array(
                'id'          => '_hide_atc_logged_out',
                'label'       => __('Hide "Add to Cart" for logged-out users', 'woocommerce'),
                'description' => __('Hide only the Add to Cart button for logged-out users.', 'woocommerce'),
            ));
            ?>
        </div>

        <div class="options_group">
            <p class="form-field">
                <label for="_hide_add_to_cart_button_user_roles"><?php esc_html_e('Hide "Add to Cart" for specific user roles', 'woocommerce'); ?></label>
                <select id="_hide_add_to_cart_button_user_roles" name="_hide_add_to_cart_button_user_roles[]" class="wc-hide-atc-product-roles" multiple="multiple" style="width:300px;">
                    <?php
                    $roles       = get_editable_roles();
                    $saved_roles = get_post_meta(get_the_ID(), '_hide_add_to_cart_button_user_roles', true);
                    $saved_roles = is_array($saved_roles) ? $saved_roles : array();
                    foreach ($roles as $role_key => $role_data) {
                        $selected = in_array($role_key, $saved_roles) ? 'selected="selected"' : '';
                        echo '<option value="' . esc_attr($role_key) . '" ' . $selected . '>' . esc_html($role_data['name']) . '</option>';
                    }
                    ?>
                </select>
                <button type="button" class="select-all-product-roles button"><?php _e('Select All', 'woocommerce'); ?></button>
                <span class="description"><?php esc_html_e('Select user roles for which the Add to Cart button should be hidden.', 'woocommerce'); ?></span>
            </p>
        </div>
    </div>
    <?php
}

add_action('woocommerce_process_product_meta', 'save_catalog_mode_product_fields');
function save_catalog_mode_product_fields($post_id) {
    // Existing product-level fields
    $catalog_mode_enabled = isset($_POST['_catalog_mode_enabled']) ? 'yes' : 'no';
    update_post_meta($post_id, '_catalog_mode_enabled', $catalog_mode_enabled);

    $catalog_mode_logged_in_only = isset($_POST['_catalog_mode_logged_in_only']) ? 'yes' : 'no';
    update_post_meta($post_id, '_catalog_mode_logged_in_only', $catalog_mode_logged_in_only);

    $catalog_mode_logged_out_only = isset($_POST['_catalog_mode_logged_out_only']) ? 'yes' : 'no';
    update_post_meta($post_id, '_catalog_mode_logged_out_only', $catalog_mode_logged_out_only);

    $hide_add_to_cart = isset($_POST['_hide_add_to_cart_button']) ? 'yes' : 'no';
    update_post_meta($post_id, '_hide_add_to_cart_button', $hide_add_to_cart);

    // New product-level Hide Add to Cart fields
    $hide_atc_logged_in = isset($_POST['_hide_atc_logged_in']) ? 'yes' : 'no';
    update_post_meta($post_id, '_hide_atc_logged_in', $hide_atc_logged_in);

    $hide_atc_logged_out = isset($_POST['_hide_atc_logged_out']) ? 'yes' : 'no';
    update_post_meta($post_id, '_hide_atc_logged_out', $hide_atc_logged_out);

    if (isset($_POST['_hide_add_to_cart_button_user_roles']) && is_array($_POST['_hide_add_to_cart_button_user_roles'])) {
        $sanitized_roles = array_map('sanitize_text_field', $_POST['_hide_add_to_cart_button_user_roles']);
        update_post_meta($post_id, '_hide_add_to_cart_button_user_roles', $sanitized_roles);
    } else {
        update_post_meta($post_id, '_hide_add_to_cart_button_user_roles', array());
    }
}
See the full code

Pro Tips from My Experience

  • Start by testing with just a few products or categories
  • Use the user roles feature to create a tiered viewing system
  • Remember to clear your cache after making changes
  • Consider adding a “Request Quote” button when hiding prices
  • Add a note explaining why prices are hidden to avoid confused customers

A Word of Caution

If you’re using a caching plugin (and you should be!), make sure to clear your cache after setting up catalog mode. Also, test the features while logged out to make sure everything works as expected for your visitors.

Over to You

That’s it! You’ve just added a powerful catalog mode feature to your WooCommerce store. Have you tried implementing something similar on your site? Let me know in the comments how you use catalog mode in your business!

P.S. Remember to back up your site before adding any custom code. I’ve learned this lesson the hard way over the years!

Do you want to thank me and buy me a beer?

Every donation is entirely welcome but NEVER required. Enjoy my work for free but if you would like to thank me and buy me a beer or two then you can use this form here below.

Donation Form (#2)

Here are some of my favorite WordPress tools

Thanks for reading this article! I hope it's been useful as you work on your own websites and e-commerce sites. I wanted to share some tools I use as a WordPress developer, and I think you'll find them helpful too.

Just so you know, these are affiliate links. If you decide to use any of them, I'll earn a commission. This helps me create tutorials and YouTube videos. But honestly, I genuinely use and recommend these tools to my friends and family as well. Your support keeps me creating content that benefits everyone.

Themes: Over the past few years, I've consistently relied on two primary themes for all sorts of projects: the Blocksy theme and the Kadence Theme. If you explore this website and my YouTube channel, you'll come across numerous tutorials that delve into these themes. If you're interested in obtaining a 10% discount for both of these themes, then:

Code Snippets Manager: WPCodeBox allows you to add code snippets to your site. Not only that, but it also provides you with the capability to construct and oversee your WordPress Code Snippets library right in the cloud. You can grab it with the 20% discount here (SAVE 20% Coupon: WPSH20).

Contact forms: There are hundreds of contact forms out there but Fluent Forms is the one I like the most. If you need a 20% discount then use this link (save 20% coupon is WPSH20).

Gutenberg add-ons: If I need a good Gutenberg blocks add-on then Kadence Blocks is the one I have used the most. You’ll get a 10% discount with the coupon SIMPLEHACKS here.

Website migration: While building a website you probably need a good plugin that can help you with the migration, backups, restoration, and staging sites. Well, WpVivid is the one I have used for the last couple of years. If you use this link along with the WPSH20 coupon you’ll get a 20% discount.

Woocommerce extensions: There are a bunch of Woocommerce extensions that I like but the one that stands out is Advanced Dynamic Pricing. Once again, you’ll get a 20% discount if you use this link here (save 20% coupon is WPSH20)

Web Hosting: If you would like to have a really fast and easy-to-use managed cloud hosting, then I recommend Verpex Hosting (see my review here). By the way, this site is hosted in Verpex.)

To see all my most up-to-date recommendations, check out this resource that I made for you!

Janek T.
Janek T.

Improve this text: {CLIPBOARD}

- I have been passionate about Wordpress since 2011, creating websites and sharing valuable tips on using Wordpress and Woocommerce on my site.
- Be the first to receive notifications about new tutorials by subscribing to my Youtube channel .
- Follow me on Twitter here

Articles: 140