Product Types
Welcome to a complete WooCommerce product types tutorial, here we are going to dive into the details on how to get product type, create a custom product type and hide the default ones.
Get Product Type of a WooCommerce Product
In case you forget there are four default WooCommerce product type and a custom one can be created as well. So, how you can check a product type easily in code?
There are actually two of doing it:
get_type()
method ofWC_Product
class.is_type()
method of the same class.
So in order to get a product type by ID you can use either this code:
$product_id = 541;
$product = wc_get_product( $product_id );
// check if variable product
if( 'variable' === $product->get_type() ) {
// doing some stuff for variable products
}
Or this one:
$product_id = 541;
$product = wc_get_product( $product_id );
// check if variable product
if( $product->is_type( 'variable' ) ) {
// doing some stuff for variable products
}
So both of these methods are going to work. You can also check if product is Simple simple
, Grouped grouped
or Affiliate/External external
.
Check if product is Downloadable or Virtual
“Downloadable” and “Virtual” are not exactly the types of products, so you can not check them using get_type()
or is_type()
methods. But you can use is_downloadable()
to check if product is a downloadable one and is_virtual()
method for virtual product check.
$product_id = 541;
$product = wc_get_product( $product_id );
if( $product->is_downloadable() ) {
// seems like it is a downloadable product!
}
if( $product->is_virtual() ) {
// it is a virtual one
}
Remove Default Product Types
Before doing it you basically need to understand that product_type
is a custom taxonomy with hidden UI. And each product type like “Simple”, “Grouped”, “Variable” etc are its taxonomy terms.
Well, you might think – if product types are taxonomy terms, I just have to remove a certain term from the database? You could try, but know what? Product types are hardcoded in WooCommerce files and we have to use product_type_selector
to hook them.
Let’s remove “Grouped” and “External” product types:
add_filter( 'product_type_selector', 'rudr_remove_grouped_and_external' );
function rudr_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 another type.
You won’t be able to select the removed product types from the dropdown in the Product data metabox:

They’ll also disappear from the “Filter by product type” on the All products page:

By the way, if you’re eager to know how to remove “→ Downloadable” and “→ Virtual” options from this filter, check this tutorial.
How to Create Custom Product Type for WooCommerce
Ok, the question is – why you would ever need to create a custom product type? To improve user experience of course. I don’t know if you are familiar with WooCommerce Subscriptions plugin, but a subscription product is a product of a custom type. It is very convenient because:
- You could easily configure what product settings (and tabs) are going to be available in Product Data metabox.
- Additional filters on All Products page.
- You could
type
parameter when querying the products withwc_get_products()
andWC_Product_Query
. - It is also possible to condition product types with
is_type()
orget_type()
method, which has been already discussed above. - Oh yes, and you can override default
WC_Product
methods, we will talk about it as well.
Register Custom Product Type as an extension to WC_Product class
You maybe know of maybe not, but every default WooCommerce product type has its own PHP class that extends WC_Product
default product class, for example WC_Product_Simple
, WC_Product_Variable
, WC_Product_External
, WC_Product_Grouped
, so it is kind of obvious, that in order to create a custom product type we need to create another PHP class.
add_action( 'init', function() {
class WC_Product_Gift extends WC_Product {
public function get_type() {
return 'gift';
}
}
} );
add_filter( 'woocommerce_product_class', function( $php_classname, $product_type ) {
if ( 'gift' === $product_type ) {
$php_classname = 'WC_Product_Gift';
}
return $php_classname;
}, 10, 2 );
As you can see from the above code, I decided that my custom product type would be gift
and its classname would be WC_Product_Gift
.
I have already refactored get_type()
method of WC_Product
class, but it is possible to refactor some other methods like get_price()
. But before we do any other custom stuff, let’s add our custom type into the list.
We can do it the same way we removed the default ones, with product_type_selector
filter hook.
add_filter( 'product_type_selector', 'rudr_add_gift_type' );
function rudr_add_gift_type( $product_types ){
$product_types[ 'gift' ] = 'Gift';
return $product_types;
}
Wait, do you know where to insert all the code? In case you don’t, this tut is for you.
That’s the result, “Gift” custom product type is available to use:

Show “General” tab and hide “Attributes” for a custom product type
If look at the screenshot above one more time, you will see that product settings are different when you switch between product types. Even product data tabs are changing. Why this is happening is already described in another tutorial, but now we are going to look at some practical examples.
And my practical example would be to put back “General” tab with prices and to hide “Attributes” for our custom product type.
The long story short this whole chapter is about using show_if_{type}
and hide_if_{type}
CSS classes, or to say exactly show_if_gift
and hide_if_gift
classes.
So let’s begin with the easy one – hiding “Attributes” tab. In my product data metabox tutorial I already mentioned woocommerce_product_data_tabs
filter hook. So, here we are:
add_filter( 'woocommerce_product_data_tabs', function( $tabs ){
// add hide_if_gift class for "Attributes" tab
$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 if it contains any HTML fields available for a certain product type. We have two options here:
- Add another section with fields with
woocommerce_product_options_general_product_data
filter hook withshow_if_gift
CSS class. How to do it. - Add this
show_if_gift
CSS class to pricing fields using JavaScript, here is the code:
jQuery( document ).ready( function() {
jQuery( '#general_product_data .pricing' ).addClass( 'show_if_gift' );
});
Overriding methods
I added only get_type()
method to the class, but you can redefine other methods too, for example, you can calculate the price of your 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 );
}

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
Hi Misha,
I am trying to create an auction site as simple as classifieds. I am using premium Woocommerce simple auctions which add auction product type in WC with special attributes + premium WCFM ultimate as front-end manager allowing users to post their products. But it means users have to create a step by step store asking lot of questions (name of store, shipping rates etc..) and when set, user is face with all product types to choose from: simple product, grouped… + auction.
Not only the user dashboard looks like a 747 cockpit with tons of options, which is great btw, but totally out of proportion for a one time user trying to get a good price for his grandma set of porcelain.
Now Dokan free is pretty straight ahead and offers a user front-end with only one product type: simple product.
My question is: where should I pass your code removing all other product types, leaving only auction, and see what happens with Dokan, if auctions features follow that change of product. Do I copy your code by creating a new folder with a new file in WC folder, just a new file, editing a file and which one and where. My actual under the hood experience allows me to add some lines when I’m shown where, add html ads, but that’s painfully all my knowledge.
Thanks for reading,
have a wonderful day.
Philippe
Awesome! Thanks a lot. Nice article which safed me a lot of time :)
very usefull