---
title: "External component events"
slug: "external-component-events"
abstract: "Overview of the events that an external page component can subscribe to."
---
# External component events

You can [configure an **External** page component](urn:resource:component:1281583) to subscribe to various system events. Whenever one of those events occurs, related data is passed to the page component.

## Entity events

The following table lists entity events.

- Event: Trigger
- `ENTITY_UPDATED`: The `entity (id)` is updated.
- `ENTITY_CREATED`: An `entity` is created.
- `ENTITY_SAVED`: The `entity (id)` is saved.
- `ENTITY_REFRESHED`: The `entity (id)` is refreshed.
- `ENTITY_DELETED` (subscribe event): Content Hub publishes this event to notify external components when an `entity (id)` has been deleted.
- `ENTITY_DELETED` (publish event): External components can publish this event to notify Content Hub that an `entity (id)` has been deleted.`DefinitionName` is required. If no entity `id` is provided, all components listening to any entity of that definition will be notified.`Id` is optional. If specified, only components listening to that particular entity will be notified.
- `ENTITY_CHANGED`: The `memberName` is changed on the entity (id).
- `SEARCH_FINISHED`: A search is completed.
- `SELECTION_CHANGED`: A selection changes.
- `ANNOTATION_SELECTED`: An annotation is selected on the **Annotations** sidebar.
- `ANNOTATION_DESELECTED`: An annotation is deselected on the **Annotations** sidebar.
- `CLOSE_MEDIA_SELECTOR`: The media selection dialog is closed.

## Realtime events

The following table lists realtime events.

| Event | Trigger | Event Data |
| --- | --- | --- |
| `realtime (notificationType)` | A *real-time notification* is received. | Notification parameters |

The following data is passed to the events:

```json
ENTITY_CREATED: {
    definitionName: string;
    id?: number;
    modified?: Date;
    stopPropagation?: boolean;
};

ENTITY_DELETED: {
    definitionName: string;
    id?: number;
};

ENTITY_SAVED: {
    id: number;
    definitionName: string;
    modified?: Date;
};

ENTITY_REFRESHED: {
    id: number;
    modified: Date;
};

ENTITY_UPDATED: {
    id: number;
    definitionName?: string;
    modified: Date;
};

ENTITY_CHANGED: {
    id: number;
    type: "systemProperty | property | relation";
    memberName: string;
    value: unknown;
};

SEARCH_FINISHED: {
    searchIdentifier: string;
    fullText: string;
    filters: Array<FieldFilterResponseResource>;
    ids: Array<number>;
};

SELECTION_CHANGED: {
    selectionPoolIdentifier: string;
    subPoolId?: number;
    action: "add" | "remove" | "clear";
    ids?: Array<number>;
    definitionNames: Array<string>;
}

```

## Entity saved event

To subscribe to the `ENTITY_SAVED` event, use the following code:

```json
const onEntitySaved = (evt: Event): void => {
    const { definitionName, id } = (evt as CustomEvent<{ definitionName: string; id: number }>).detail;

    alert(`Entity with id ${id} and definition ${definitionName} was saved`);
};

window.addEventListener("ENTITY_SAVED", onEntitySaved);

```

## Entity changed event

The format of the data received following an `ENTITY_CHANGED` event depends on the type of data that was changed. For example, if a system property was changed, the data received has the following format:

```json
{
  id: number;
  type: "systemProperty",
  memberName: string;
  value: unknown;
}

```

If a normal property was changed, the data received has the following format:

```json
{
  id: number;
  type: "property",
  memberName: string;
  value: unknown;
}

```

If a relation with the `allow_navigation` enabled changes, the data received has the following format:

```json
{
  id: number;
  type: "relation",
  memberName: string;
  value: Array<number>;
  allowNavigation: true;
  role?: "Parent" | "Child" | undefined;
}

```

If a relation with the `allow_navigation` disabled changes, the data received has the following format:

```json
{
  id: number;
  type: "relation",
  memberName: string;
  allowNavigation: false;
  role?: "Parent" | "Child" | undefined;
}

```

## Search finished event

When monitoring the `SEARCH_FINISHED` event, use the `getEventSearchIdentifier` [method](urn:resource:component:1281583) to compare the `searchIdentifier` with the one from the event.

```json
const onSearchFinished = (evt: Event): void => {
      const {
        filters,
        searchIdentifier: eventSearchIdentifier, // We rename the property to eventSearchIdentifier.
        fullText,
      } = (
        evt as CustomEvent<{
          searchIdentifier: string;
          fullText: string;
          filters: Array<FieldFilterResponseResource>;
          ids: Array<number>;
        }>
      ).detail;

      // We check if the searchIdentifier on the event is the one we are interested in.
      if (
        eventSearchIdentifier === getEventSearchIdentifier(searchIdentifier)
      ) {
        setAppliedSearchFilters(filters);
        setFullTextFilterValue(fullText);
      }
    };

    window.addEventListener("SEARCH_FINISHED", onSearchFinished);

```

> [!note]
> In React, the `ENTITY_LOADED` and `ENTITY_UNLOADED` events are no longer required as the entity is already loaded when the external component renders. We recommend that the first initialization takes place in the root of the code instead of the render method; otherwise, the initialization logic repeats unnecessarily.