---
title: Exclude Categories from Search Results
slug: klevu-magento-v4/exclude-categories-from-search-results
docTags: 
createdAt: 2024-10-04T15:13:48.303Z
---

By default, all categories indexed to Klevu have a visibility of `search`.&#x20;
There are 2 possible approaches to change this depending on your needs.
The first is to exclude the category from the sync altogether using an `isIndexableCondition`.&#x20;
The second is to change the visibility sent in the data.

### Is Indexable Condition

:::hint{type="warning"}
Excluding the category this way would result in no products showing for this category on the frontend of your store for Category Navigation.
:::

To do this we inject an `isIndexableCondition` into the `isIndexableConditions` array for the virtual type `Klevu\IndexingCategories\Service\Determiner\IsIndexableDeterminer`

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

```xml
<virtualType name="Klevu\IndexingCategoriess\Service\Determiner\IsIndexableDeterminer">
    <arguments>
        <argument name="isIndexableConditions" xsi:type="array">
            <item name="pageIsIndexableCondition"
                  xsi:type="object">Vendor\Module\Service\Determiner\CategoryIdIsIndexableCondition</item>
        </argument>
    </arguments>
</virtualType>

```
:::

Create that class, which must implement the `IsIndexableConditionInterface`&#x20;

:::CodeblockTabs
Vendor/Module/Service/Determiner/CategoryIdIsIndexableCondition.php

```php
<?php

namespace Vendor\Module\Service\Determiner;

use Klevu\IndexingApi\Service\Determiner\IsIndexableConditionInterface;
use Magento\Catalog\Api\Data\CategoryInterface;


class CategoryIdIsIndexableCondition implements IsIndexableConditionInterface
{
    /**
     * Edit routes as required
     * Alternatively inject these via di.xml
     *
     * @param int[]
     */
    private array $excludedCategories = [
        4,
        23,
    ];
    
    public function execute(
        ExtensibleDataInterface|PageInterface $entity,
        StoreInterface $store,
    ): bool {
        if (!($entity instanceof CategoryInterface)) {
            throw new \InvalidArgumentException(
                sprintf(
                    'Invalid argument provided for "$entity". Expected %s, received %s.',
                    CategoryInterface::class,
                    get_debug_type($entity),
                ),
            );
        }
        
        return !in_array(
            needle: (int)$entity->getId(), 
            haystack: $this->excludedCategories, 
            strict: true,
        );
    }
}

```
:::

See [Entities Is Indexable Determiner](https://docs.klevu.com/klevu-magento-v4/entities-is-indexable-determiner) for more information.

### Change Visibility in the Synced Data

To change the data synced we must override the pipeline YAML for categories.

Create the override YAML file

:::CodeblockTabs
Vendor/Module/etc/pipeline/add\_update.yml

```yaml
stages:
  iterateIndexingRecordsBatch:
    stages:
      iterateIndexingRecords:
        stages:
          processCategory:
            stages:
              createRecord:
                stages:
                  attributes:
                    stages:
                      visibility: Vendor_Module::etc/pipeline/category/attributes/visibility.yml 
```
:::

Create the imported visibility YAML file.
It is possible to do this all in one YAML file, but separating it into multiple files makes it easier to read.
To remove all categories from search.

:::CodeblockTabs
Vendor/Module/etc/pipeline/category/attributes/visibility.yml&#x20;

```yaml
stages:
  -
    pipeline: Stage\StaticValue
    args:
      value: [""]
```
:::

To remove some categories from search. Take the current category and pass it into a transformer. This transformer should return an array of strings containing with   or `search`.

:::CodeblockTabs
Vendor/Module/etc/pipeline/category/attributes/visibility.yml&#x20;

```yaml
stages:
  -
    pipeline: Stage\Extract
    args:
      extraction: currentCategory::
      transformations: 
        - ToVisibility
```
:::

Create the transformer to handle the visibility

:::CodeblockTabs
Vendor/Module/Pipeline/Transformer/ToVisibility.php

```php
namespace Vendor\Module\Pipeline\Transformer;


use Klevu\Pipelines\Transformer\TransformerInterface;
use Magento\Catalog\Api\Data\CategoryInterface;


class ToVisibility implements TransformerInterface
{
    /*
     * @return string[]
     */
    public function transform(
        mixed $data,
        ?ArgumentIterator $arguments = null,
        ?\ArrayAccess $context = null,
    ): array {
    
    if (!($data instanceof CategoryInterface)) {
        throw new InvalidInputDataException(
            transformerName: $this::class,
            expectedType: CategoryInterface::class,
            arguments: $arguments,
            data: $data,
        );
    }
    
    return $this->visibilityProvider->get(
        category: data,
    );
}
```
:::

If you create a transformer in a custom module it must be registered with the pipelines before it can be used. See [Registering Transformers](https://docs.klevu.com/klevu-magento-v4/entities-registering-transformers) for more information.

Alternatively we could add an attribute to the category for visibility and use that instead of a transformer. e.g.&#x20;

:::CodeblockTabs
Vendor/Module/etc/pipeline/category/attributes/visibility.yml&#x20;

```yaml
stages:
  -
    pipeline: Stage\Extract
    args:
      extraction: currentCategory::getVisibility()

```
:::

Assumes `getVisibility` would return either   or `search`. If it returned an integer then we'd have to map that. see the visibility YAML for products `module-m2-indexing-products/etc/pipeline/product/attributes/visibility.yml`

See [Pipeline Customisation](https://docs.klevu.com/klevu-magento-v4/entities-pipelines-customisation) for more information on how to customise pipelines.
