---
title: Custom Product Types
slug: klevu-magento-v4/entities-custom-product-types
docTags: 
createdAt: 2024-08-06T17:02:22.181Z
---

Product types are injected via this virtualType `Klevu\IndexingProducts\Service\Provider\EntityProviderProvider` in the indexing products module `etc/di.xml`

:::CodeblockTabs
magento2-plugin/module-m2-indexing-products/etc/di.xml

```xml
<virtualType name="Klevu\IndexingProducts\Service\Provider\EntityProviderProvider"
             type="Klevu\Indexing\Service\Provider\EntityProviderProvider">
    <arguments>
        <argument name="entityProviders" xsi:type="array">
            <item name="simple"
                  xsi:type="object">Klevu\IndexingProducts\Service\Provider\ProductEntityProvider\Simple</item>
            <item name="virtual"
                  xsi:type="object">Klevu\IndexingProducts\Service\Provider\ProductEntityProvider\Virtual</item>
            <item name="downloadable"
                  xsi:type="object">Klevu\IndexingProducts\Service\Provider\ProductEntityProvider\Downloadable</item>
            <item name="grouped"
                  xsi:type="object">Klevu\IndexingProducts\Service\Provider\ProductEntityProvider\Grouped</item>
            <item name="bundle"
                  xsi:type="object">Klevu\IndexingProducts\Service\Provider\ProductEntityProvider\Bundle</item>
            <item name="configurable"
                  xsi:type="object">Klevu\IndexingProducts\Service\Provider\ProductEntityProvider\Configurable</item>
            <item name="configurable_variants"
                  xsi:type="object">Klevu\IndexingProducts\Service\Provider\ProductEntityProvider\ConfigurableVariants</item>
        </argument>
    </arguments>
</virtualType>
```
:::

Merchants can add to this `EntityProviderProvider`&#x20;
e.g.

:::CodeblockTabs
Vendor/Module/etc/di.xml

```xml
<virtualType name="Klevu\IndexingProducts\Service\Provider\EntityProviderProvider">
    <arguments>
        <argument name="entityProviders" xsi:type="array">
            <item name="custom_type"
                  xsi:type="object">Vendor\Module\Service\Provider\ProductEntityProvider\CustomTypeProvider</item>
        </argument>
    </arguments>
</virtualType>
```
:::

There are 2 ways in which this `CustomTypeProvider` can be generated.

1\. (Recommended) Use `virtualTypes`, as the Klevu module does, and pass your custom `productType`
e.g

:::CodeblockTabs
Vendor/Module/etc/di.xml

```xml
<!-- Virtual type for ProductEntityProvider -->
<virtualType name="Vendor\Module\Service\Provider\ProductEntityProvider\CustomTypeProvider"
             type="Klevu\IndexingProducts\Service\Provider\ProductEntityProvider">
    <arguments>
        <argument name="productEntityCollection"
                  xsi:type="object">Vendor\Module\Service\Provider\Discovery\ProductEntityCollection\CustomType</argument>
    </arguments>
</virtualType>

<!-- Virtual type for the ProductEntityCollection used above --> 
<!-- This will return all product of type "custom_type" -->
<virtualType name="Vendor\Module\Service\Provider\Discovery\ProductEntityCollection\CustomType"
             type="Klevu\IndexingProducts\Service\Provider\Discovery\ProductEntityCollection">
    <arguments>
        <argument name="productType" xsi:type="string">custom_type</argument>
    </arguments>
</virtualType>
```
:::

2\. Create a class. This is recommended if you need to filter the returned products on more than the product type.
The provider must implement `Klevu\IndexingApi\Service\Provider\EntityProviderInterface`
e.g.

:::CodeblockTabs
Vendor/Module/etc/di.xml

```xml
<virtualType name="Vendor\Module\Service\Provider\ProductEntityProvider\CustomTypeProvider"
             type="Klevu\IndexingProducts\Service\Provider\ProductEntityProvider">
    <arguments>
        <argument name="productEntityCollection"
                  xsi:type="object">Vendor\Module\Service\Provider\Discovery\ProductEntityCollection\CustomType</argument>
    </arguments>
</virtualType>

```
:::

Create the provider

:::CodeblockTabs
Vendor/Module/Service/Provider/Discovery/ProductEntityCollection/CustomTypeProvider.php

```php
<?php

namespace Vendor\Module\Service\Provider\Discovery\ProductEntityCollection;

use Klevu\IndexingApi\Service\Provider\EntityProviderInterface;

class CustomType implements EntityProviderInterface
{
    /**
     * ProductCustomTypeEntityCollection $productCustomTypeEntityCollection
     */
    public function __construct(
        ProductCustomTypeEntityCollection $productCustomTypeEntityCollection,
    ) {
        $this->productCustomTypeEntityCollection = $productCustomTypeEntityCollection;
    }
    
    /**
     * @param StoreInterface|null $store
     * @param int[]|null $entityIds
     *
     * @return ProductCollection
     */
    public function get(
        ?StoreInterface $store = null, 
        ?array $entityIds = [],
    ): ?\Generator {
        $collection = $this->productCustomTypeEntityCollection->get(
            store: $store, 
            entityIds: $entityIds,
        );
        foreach ($collection as $product) {
            yield $product;
        }
    }
}
```
:::

Here `ProductCustomTypeEntityCollection` is a class that returns a collection of the custom product type.

