> For the complete documentation index, see [llms.txt](https://docs.umbraco.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.umbraco.com/umbraco-cms/19.latest/develop-with-umbraco/search/extending-search/indexing-notification-handling.md).

# Indexing Notification Handling

Describes the indexing notification system and how to interact with it as a developer

Before content is pushed to any content index, `ContentIndexingNotification` is fired. This notification lets you manipulate the data going into an index, or entirely prevent it from being indexed.

## Keep it lightweight

The `ContentIndexingNotification` fires for *all* content index updates, and the notification handling is not subject to any [caching](/umbraco-cms/19.latest/develop-with-umbraco/search/extending-search/database-cache-for-index-values.md).

If a notification handler performs expensive operations, this can introduce a large performance overhead. Consider creating [content indexers](/umbraco-cms/19.latest/develop-with-umbraco/search/extending-search/gathering-data-with-content-indexers.md) for tasks like:

* Complex value calculation.
* Content look-ups, for example, through the published cache.
* Out-of-process operations, including database lookups and external service calls.

## Manipulating data going into an index

The notification contains a `Fields` collection of fields aggregated from all the [content indexers](/umbraco-cms/19.latest/develop-with-umbraco/search/extending-search/gathering-data-with-content-indexers.md). These fields can be manipulated by the notification handler.

{% hint style="warning" %}
Be careful if you change or remove any of the [system fields](/umbraco-cms/19.latest/develop-with-umbraco/search/system-fields.md), as this might corrupt the index.
{% endhint %}

In the following example, the content being indexed might contain a `length` field. This is a radio button list property, and thus it [produces keywords](/umbraco-cms/19.latest/develop-with-umbraco/search/built-in-property-editors.md) for filtering and faceting.

Keywords are not available for full-text querying by default. You can use a notification handler to amend this for the `length` field:

{% code title="MakeLengthSearchableNotificationHandler.cs" %}

```csharp
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Notifications;
using Umbraco.Cms.Core.Search.Indexing;

namespace My.Site.NotificationHandlers;

public class MakeLengthSearchableNotificationHandler
    : INotificationHandler<ContentIndexingNotification>
{
    public void Handle(ContentIndexingNotification notification)
    {
        // Find the "length" field and make sure it has any keywords set.
        var field = notification.Fields.FirstOrDefault(field => field.FieldName == "length");
        if (field?.Value.Keywords is null)
        {
            return;
        }

        // Update the fields for indexing (the collection itself is immutable):
        // 1. Remove the original field.
        // 2. Add a replacement field with the Texts collection included, to make the length values searchable.
        notification.Fields = notification.Fields
            .Except([field])
            .Union([
                field with { Value = new IndexValue
                {
                    Keywords = field.Value.Keywords,
                    Texts = field.Value.Keywords
                } }
            ])
            .ToArray();
    }
}
```

{% endcode %}

{% hint style="info" %}
The example works if you need to target a specific property value (the `length` property in this case).

If you want to change the indexing of *all* property values for a given property editor, use a [property value handler](/umbraco-cms/19.latest/develop-with-umbraco/search/extending-search/index-values-for-property-editors.md) instead.
{% endhint %}

## Preventing content from being indexed

Cancelling the notification will prevent content from being added to the target index:

{% code title="OmitSettingsFromPublishedContentIndexNotificationHandler.cs" %}

```csharp
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Events;
using Umbraco.Cms.Core.Notifications;

namespace My.Site.NotificationHandlers;

public class OmitSettingsFromPublishedContentIndexNotificationHandler
    : INotificationHandler<ContentIndexingNotification>
{
    // The ID of the "Settings" content type (as a string).
    private const string SettingsContentTypeId = "34068730-7E9E-4A04-BA10-B95873EE7E59";
    
    public void Handle(ContentIndexingNotification notification)
    {
        // This notification handler only deals with the published content index.
        if (notification.IndexAlias is not Constants.Search.IndexAliases.PublishedContent)
        {
            return;
        }

        // Find the system field for content type ID.
        var contentTypeIdField = notification
            .Fields
            .FirstOrDefault(field => field.FieldName == Constants.Search.FieldNames.ContentTypeId);

        // Grab the content type ID from the keywords collection.
        var contentTypeId = contentTypeIdField?.Value.Keywords?.FirstOrDefault();
        
        // No content type ID could be found. Prevent the content from being indexed to be on the safe side.
        // NOTE: This should never happen.

        // Prevent the content from being indexed in the published content index if either:
        // 1. The content is of type "Settings".
        // 2. The content type could not be determined. This should never happen, but let's be on the safe side.
        notification.Cancel = contentTypeId is null || contentTypeId.InvariantEquals(SettingsContentTypeId);
    }
}
```

{% endcode %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation by asking a question.

Perform an HTTP GET request on the following URL with the `ask` and `goal` query parameters:

```
GET https://docs.umbraco.com/umbraco-cms/19.latest/develop-with-umbraco/search/extending-search/indexing-notification-handling.md?ask=<question>&goal=<user_goal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is what the user is ultimately trying to achieve, the reason they need the answer. Sharing it helps GitBook give you a better, more relevant answer. A goal is most helpful when it describes the outcome the user wants rather than restating the question. For example, with `ask=how do I create an API token`, a goal like `automate deployments from our CI pipeline` lets GitBook tailor the answer to that use case.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
