How to Create Custom Product Type in Magento2

By default, Magento 2 has six types of products which are simple, configurable, virtual, downloadable, bundle and grouped products. Each of this product types has multiple unique features and attributes. All these product types may fulfill the merchant needs. But in some cases, they may require to create custom product types to extend their need in Magento 2. So In this post, we will see how to create a new product type in Magento 2.

Define a new module

Here we are going to create a new custom module based on Magento 2 structure for adding custom product type.

Path: <Magento 2 root directory>/app/code/BlogTreat/CustomProductType/

Create module.xml file in the below file path to define the new module,

File Path: app/code/BlogTreat/CustomProductType/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="BlogTreat_CustomProductType" setup_version="1.0.0">

Next, create registration.php file in the below file path,

File Path: app/code/BlogTreat/CustomProductType/registration.php


Add Custom Product Type:

Create product_types.xml file in the below file path to define a custom product type

File Path: app/code/BlogTreat/CustomProductType/etc/product_types.xml

<?xml version="1.0"?>
<config xmlns:xsi="" xsi:noNamespaceSchemaLocation="urn:magento:module:Magento_Catalog:etc/product_types.xsd">
    <type name="custom_product_type" label="Custom Product Type" modelInstance="BlogTreat\CustomProductType\Model\Product\Type\CustomType" indexPriority="100" sortOrder="100" isQty="true">
        <type name="custom_product_type" />

In the above code,

  • name: new product type code
  • label: product type name
  • modelInstance: new product model
  • indexPriority: priority index
  • sortOrder: position number in the sort list
  • isQty: whether it has a quantity

Then, create modelInstance file in the below file path, it must inherit from the \Magento\Catalog\Model\Product\Type\AbstractType base class.

File Path: app/code/BlogTreat/CustomProductType/Model/Product/Type/CustomType.php

namespace BlogTreat\CustomProductType\Model\Product\Type;
class CustomType extends \Magento\Catalog\Model\Product\Type\AbstractType {

    const TYPE_ID = 'custom_product_type';
     * {@inheritdoc}
    public function deleteTypeSpecificData(\Magento\Catalog\Model\Product $product)
        // method intentionally empty

Finally, create a setup installer file in the below file path

File Path: app/code/BlogTreat/CustomProductType/Setup/InstallData.php

namespace BlogTreat\CustomProductType\Setup;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\InstallDataInterface;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;

 * Class InstallData
 * @package 
class InstallData implements InstallDataInterface
     * EAV setup factory
     * @var EavSetupFactory
    private $eavSetupFactory;

     * Init
     * @param EavSetupFactory $eavSetupFactory
    public function __construct(
        EavSetupFactory $eavSetupFactory
    ) {
        $this->eavSetupFactory = $eavSetupFactory;

     * @param ModuleDataSetupInterface $setup
     * @param ModuleContextInterface $context
    public function install(ModuleDataSetupInterface $setup, ModuleContextInterface $context)

        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

        // associate these attributes with new product type
        $attributes = [

        // make these attributes applicable to new product type
        foreach ($attributes as $attributeCode) {
            $relatedProductTypes = explode(
                $eavSetup->getAttribute(\Magento\Catalog\Model\Product::ENTITY, $attributeCode, 'apply_to')
            if (!in_array(\BlogTreat\CustomProductType\Model\Product\Type\CustomType::TYPE_ID, $relatedProductTypes)) {
                $relatedProductTypes[] = \BlogTreat\CustomProductType\Model\Product\Type\CustomType::TYPE_ID;
                    implode(',', $relatedProductTypes)

After completing the above steps, run the below command in CLI to upgrade the setup,

php magento setup:upgrade

Then, clear the cache and check your admin side.

Hope this helps.

Leave a Reply

Your email address will not be published. Required fields are marked *