Product Types Tutorial

Basically the product_type is a custom taxonomy with hidden UI. And each product type like “Simple”, “Grouped”, “Variable” etc are the taxonomy terms.

Removing a Product Type You Don’t Need

Well, you may think – if product types are taxonomy terms, I just have to remove a certain term from the database?

Ahaha 😁 You could try, but know what? Product types are hardcoded in WooCommerce files. And you can use product_type_selector to hook them, let’s try right now.

What if I want to remove Grouped and External products?

add_filter( 'product_type_selector', 'misha_remove_grouped_and_external' );
function misha_remove_grouped_and_external( $product_types ){
	unset( $product_types['grouped'] );
	unset( $product_types['external'] );
	//unset( $product_types['variable'] );
	return $product_types;

What exactly will happen?

Of course products on your website won’t magically become Simple products or whatever, but you are no more able to edit removed product types, you have to re-save each product as an existing type.

You won’t be able to select the removed product type from the dropdown in the Product data metabox:

Removing product types in WooCommerce

It will also disappear from the “Filter by product type” on the All products page:

Remove a type from Product type filter dropdown

By the way, if you’re eager to know how to remove “→ Downloadable” and “→ Virtual” options from this filter, check out this tutorial.

Rename a Product Type

Renaming can be done with the same product_type_selector filter hook and affects two places in admin area as well:

Example of renaming the variable product type name:

add_filter( 'product_type_selector', 'misha_rename_variable_type' );
function misha_rename_variable_type( $product_types ){
	$product_types['variable'] = 'Custom variable type name';
	return $product_types;

You can rename product types, added by third-party plugins as well, just set a higher priority for the filter hook.

How to Add Product Type Names to body_class()

I know that WooCommerce is using wc_body_class() function instead of WordPress default body_class(), but the filter we are going to use is the same – body_class.

function misha_product_type_in_body_class( $classes ){
	// get the current product in the loop
	$product = wc_get_product();
	$classes[] = 'product-type-' . $product->get_type();
	return $classes;

How to Create a WooCommerce Product Type

Okay, but what is the point of creating a new Product type?

By the way, we are going to extend WC_Product, so you can rewrite some of its method for our custom product type, which provides much more customizations.

I think the most convenient way would be to give you the complete code and to provide comments after it.

 * Step 1. Add a custom product type "term" to other hardcoded ones
add_filter( 'product_type_selector', 'misha_add_gift_product_type' );
function misha_add_gift_product_type( $product_types ){
	$product_types[ 'gift' ] = 'Gift';
	return $product_types;
 * Step 2. Each product type has a PHP class WC_Product_{type}
add_action( 'init', 'misha_create_gift_product_class' );
add_filter( 'woocommerce_product_class', 'misha_load_gift_product_class',10,2);
function misha_create_gift_product_class(){
	class WC_Product_Gift extends WC_Product {
		public function get_type() {
			return 'gift'; // so you can use $product = wc_get_product(); $product->get_type()
function misha_load_gift_product_class( $php_classname, $product_type ) {
	if ( $product_type == 'gift' ) {
		$php_classname = 'WC_Product_Gift';
	return $php_classname;

As you can see above, I added only get_type() method to the class, but you can rewrite any other method too, for example, you can calculate the price of you custom product type another way:

public function get_price( $context = 'view' ) {
	// for website contributers we have a special price
	if ( current_user_can( 'contributor' ) ) {
		return $this->get_meta( 'contributor_price', true );
	return $this->get_prop( 'price', $context );

Here it is:

Creating custom product type in WooCommerce

Show “General” tab and hide “Attributes” tab for a Custom Product Type

We’ve just created a custom product type and as you can see the Product data metabox tabs for Gift type and for Simple type differ.

What if you want to display/hide a certain default tab for the custom product type? Let’s say to display “General” tab and to hide “Attributes” tab?

Do you remember I mentioned about using show_if_{type} and hide_if_{type} CSS classes? Yes, right now we are going to use them, or to say exactly – show_if_gift and hide_if_gift.

In my product data metabox tutorial I already mentioned woocommerce_product_data_tabs filter hook. So, it is easy-peasy to hide Attributes tab:

add_filter('woocommerce_product_data_tabs', 'misha_product_data_tabs' );
function misha_product_data_tabs( $tabs ){
	$tabs['attribute']['class'][] = 'hide_if_gift';
	return $tabs;

You can find all default tab names here as well.

But unfortunately the same method doesn’t work when we are talking about “General” tab. This tab only shows up only if it contains any HTML fields available for a certain product type. We have two options here:

jQuery( document ).ready( function() {
	jQuery('#general_product_data .pricing').addClass('show_if_gift');


Hide or show tabs in Product data metabox for a particular product type
“General” tab is here, but no “Attributes” tab

Read also

Misha Rudrastyh

Misha Rudrastyh

Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.

Need some developer help? Contact me

Follow me on Twitter