---
title: "Configure the external component"
slug: "configure-the-external-component"
abstract: "How to configure the external component to use the Sitecore repository with detailed examples."
---
# Configure the external component

Before you [upload your JavaScript bundle](https://doc.sitecore.com/ch/en/users/content-hub/upload-a-javascript-bundle.html "Upload a JavaScript bundle"), ensure the interface includes the following functions:

- `render`, which runs when the component is rendered and receives one object as a parameter with data and interaction options.
- `unmount`, which runs when the component is unmounted.

> [!note]
> External components have access to a pre-authenticated Content Hub JavaScript SDK client for sending HTTP requests to Sitecore Content Hub. The SDK provides dedicated clients for common operations, and a [raw client](https://doc.sitecore.com/ch/en/developers/cloud-dev/raw-client-1523471.html) for custom requests. For requests to third-party servers, you can use standard browser APIs such as [Fetch](https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API).

## Initialize

The `createExternalRoot` function receives the `HTMLElement` (container parameter) and can be used to mount code. To initialize the **External** component, put the following initialization logic inside the root of the component, outside the `render` function:

```typescript
export default function createExternalRoot(rootElement) {
    console.log("Initializing component");

    return {
        render(props) {
            console.log("Rendering component");

            rootElement.innerHTML = "Hello world";
        },
        unmount() {
            rootElement.innerHTML = "";
        },
    };
}

```

## Render

The `render` function renders the contents of the **External** component inside a `div` in Content Hub and mounts the UI of the external component to the Document Object Model (DOM). This function receives an object containing the following data:

- `name` - string.
- `theme` - material user interface theme object providing styling properties, such as fonts and colors.
- `client` - due to issues with the pre-authenticated JavaScript SDK client's capability to serialize and deserialize complex JSON, we recommend you create your own client instance when using the [Querying](https://doc.sitecore.com/ch/en/developers/cloud-dev/querying-client-1523452.html) client. To access the client include [npm: @sitecore/sc-contenthub-webclient-sdk](https://www.npmjs.com/package/@sitecore/sc-contenthub-webclient-sdk) in your bundle and use the second argument that is passed to `createExternalRoot` to create an authenticated client instance. The new signature of `createExternalRoot` is:

    ```typescript
    createExternalRoot(
      container: HTMLElement,
      clientBuilder: (constructor: typeof ContentHubClient) => IExtendedContentHubClient
    )
    ```

    > [!note]
    > Please note that not all clients can be instantiated correctly. An example is the `entityFactory` client. To use this client, do the following:
    >
    > await client.entityFactory.createAsync("definitionName");

- `config` - [optional configuration](https://doc.sitecore.com/ch/en/users/content-hub/add-custom-json.html "Add custom JSON") passed to the external component (defaults to an empty object).
- `api` - [read-only value](https://doc.sitecore.com/ch/en/users/content-hub/configure-the-external-component.html#UUID-2de990be-2076-cf6d-3210-84f2131f6d8c_N1707922482594 "API object") (`ExternalApi`).
- `entity` - `entity | null`.
- `user` - read-only value (`ExternalUser`) with the structure as described in the next section.
- `options` - object with the structure as described in the next section.
- `icon` - an object with a method to add Content Hub icons to and HTML element.

> [!important]
> Do not pass the `theme` directly to the customer's Material UI components. The Material UI version might differ from the one used in Content Hub and, therefore, might not be fully compatible. Instead, use [CSS variables for styling](https://doc.sitecore.com/ch/en/users/content-hub/css-variables.html "CSS variables").

<details>
<summary>Get smaller bundle sizes</summary>

To get smaller bundle sizes when including the JS SDK in your external component bundle, instantiate the desired subclients using the authenticated client returned by the `clientBuilder`. For example, this approach prevents bundlers from identifying and eliminating unreachable code:

```typescript
const client = clientBuilder (ContentHubClient);
// Cannot be tree-shaken.
await client.querying.queryAsync(...);

```

To inform bundlers that you only need a specific part of the client, such as the `queryClient` in the following example, do the following:

```typescript
const queryClient = new QueryingClient (clientBuilder ());
// Can be tree-shaken.
await queryClient.queryAsync(...);

```

Calling `clientBuilder` without arguments returns the authenticated instance that is already used by the application.

</details>

<details>
<summary>Structure of the user object</summary>

The `user` object has the following data.

```typescript
export interface ExternalUser {
    id: number;
    userName: string;
    userGroups: Array<string>;
    privileges: Array<string>;
    identifier: string;
    userAvatar?: string;
}

```

</details>

<details>
<summary>Structure of the options object</summary>

The **options** object has the following data.

```typescript
/**
       * Id of the entity in the current context.
       */
      entityId?: number;

      /**
       * Culture in the current context.
       */
      culture?: CultureInfo;

      /**
       * Indicates if the page is wrapped in a modal.
       */
      isInModal?: boolean;

      /**
       * Indicates if editing is active in the current context.
       *
       */
      isEditing?: boolean;

      /**
       * The editing mode for the current context.
       *
       * "readonly" | "edit" | "inherit"
       *
       * @defaultValue `"inherit"`
       */
      editingMode?: EditingMode;

      /**
       * Indicates if the component is currently rendered inside a sidebar.
       */
      isInSidebar?: boolean;

      /**
       * Indicates if the component is currently rendered inside a tabs component.
       */
      isInTab?: boolean;

```

</details>

> [!note]
> [Examples](https://doc.sitecore.com/ch/en/users/content-hub/examples.html "Examples") on how to implement external page components are available to get you started.

## Entity property

The `entity` property is passed on the same level as the `config` and the `theme` objects. It consists of the following information:

```typescript
systemProperties: SystemProperties;
properties: Record<string, Record<CultureInfo, unknown>>;
relations: Record<string, Array<number>>;
permissions: Record<string, Optional<boolean>>;
renditions: Record<string, Array<string | URI>>;
setPropertyValue("M.Localization.Entry.Template", "some value", "en-US");
setRelatedIds("AssetMediaToAsset", [45], 0)

```

Available objects and methods include:

- [systemProperties](https://doc.sitecore.com/ch/en/users/content-hub/configure-the-external-component.html#UUID-2de990be-2076-cf6d-3210-84f2131f6d8c_N1707922643147)
- [properties](https://doc.sitecore.com/ch/en/users/content-hub/configure-the-external-component.html#UUID-2de990be-2076-cf6d-3210-84f2131f6d8c_N1707922655645)
- [relations](https://doc.sitecore.com/ch/en/users/content-hub/configure-the-external-component.html#UUID-2de990be-2076-cf6d-3210-84f2131f6d8c_N1707922664680)
- [permissions](https://doc.sitecore.com/ch/en/users/content-hub/configure-the-external-component.html#UUID-2de990be-2076-cf6d-3210-84f2131f6d8c_N1707922674133)
- [renditions](https://doc.sitecore.com/ch/en/users/content-hub/configure-the-external-component.html#UUID-2de990be-2076-cf6d-3210-84f2131f6d8c_N1707922685046 "renditions")
- [setPropertyValue](https://doc.sitecore.com/ch/en/users/content-hub/configure-the-external-component.html#UUID-2de990be-2076-cf6d-3210-84f2131f6d8c_N1707922695388)
- [Icon](https://doc.sitecore.com/ch/en/users/content-hub/configure-the-external-component.html#UUID-2de990be-2076-cf6d-3210-84f2131f6d8c_N1715764531767)
- [setRelatedIds](https://doc.sitecore.com/ch/en/users/content-hub/configure-the-external-component.html#UUID-2de990be-2076-cf6d-3210-84f2131f6d8c_N1707922704397)

### systemProperties

This object holds the system properties for the current entity.

```typescript
{
  createdBy: 6,
  id: 120,
  identifier: "kadu7AeZQym6hlFnp_mP8A",
  ...
}

```

### properties

This object holds the properties for the current entity.

```typescript
{
 Title: {
  Invariant: "title"
 },
 FileName: {
  Invariant: "file name"
 },
 Description: {
  "en-US" : "English description",
  "nl-BE" : "Dutch description"
 }
 ...
}

```

### relations

This object holds the properties for the current entity.

```typescript
{
  AssetMediaToAsset: [1029],
  AssetToAssetSelfRelation_0: [],
  AssetToAssetSelfRelation_1: [33322],
  MasterFile: [35687],
  ...
}

```

### permissions

This object holds the permissions for the current entity.

```typescript
{
  addtocollection: true,
  addversion: true,
  approve: true,
  archive: true,
  ...
}

```

### renditions

This object holds the renditions for the current entity.

```typescript
{
  bigthumbnail: ['https://localhost:5009/api/delivery/local-62f30fcc…id=6&rendition=bigthumbnail&signature=tpUrpTdJwxE']
  created_by: ['https://localhost:5009/api/delivery/local-d25e003a…d=35781&rendition=thumbnail&signature=yDa_TROvvnw']
  downloadAlternative: ['https://localhost:5009/api/delivery/local-6e770863…ndition=downloadAlternative&signature=OoDGgd7aMw8']
  downloadOriginal: ['https://localhost:5009/api/delivery/local-6e770863…&rendition=downloadOriginal&signature=V-BQoLc6jTI']
  downloadPreview: ['https://localhost:5009/api/delivery/local-01d326bd…6&rendition=downloadPreview&signature=aXPZQVw1kBE']
  ...
}

```

### setPropertyValue

This is a method to change or set the value of an entity's property. It receives the name of the property, the value, and an optional culture.

```typescript
setPropertyValue("M.Localization.Entry.Template", "some value", "en-US");

```

### IconComponent

This is a method to load [SVG icons used by Content Hub](https://ch-webapp.sitecorecontenthub.cloud/css/m-icons-demo/demo). An icon is an object passed to the main object received by the `render` function. This object has a method called `insertContentHubIconInElement`, which requires an icon name and an `HTMLElement` to render the icon.

```typescript
icon: { insertContentHubIconInElement: (icon: string, htmlElement: HTMLElement) => Promise<void> };

```

### setRelatedIds

This is a method to change or set the value of an entity's relation. It receives the relation name, the array of `entityIds`, and an optional relation role.

```typescript
setRelatedIds("AssetMediaToAsset", [45], 0)

```

The relation role that can be passed to the `setRelatedIds` method is a number.

```typescript
Parent = 0,
Child = 1

```

> [!important]
> When the **External** component is not used on a details page, the entity is `null`. In custom code make sure the property exists and is not `null`.

## API object

The `api` object holds methods to interact with the **Search**, **Selection**, and **Details** components and to display notifications:

```typescript
api:{
    search: {
      updateQuery: (searchIdentifier: string, query: string) => void;
      addFilters: (searchIdentifier: string, filters: Array<FieldFilterRequestResource>) => void;
      updateFullTextFilter: (searchIdentifier: string, text: string) => void;
      clearFullTextFilter: (searchIdentifier: string) => void;
      clearAllFilters: (searchIdentifier: string) => void;
      getEventSearchIdentifier: (searchIdentifier: string) => string;
    },
    notifier: {
      notifySuccess: (message: string) => void;
      notifyError: (message: string) => void;
      notifyWarning: (message: string) => void;
      notifyInfo: (message: string) => void;
    },
    selection: {
     addToSelection: (ids: Array<number>, selectionPoolIdentifier: string, subPoolId?: number) => void;
     removeFromSelection: (ids: Array<number>, selectionPoolIdentifier: string, subPoolId?: number) => void;
     clearSelection: (selectionPoolIdentifier: string, subPoolId?: number, definitionNames?: Array<string>) => void;
    },
    details: {
      setEntitySource: (identifier: string, entityId: number) => void
    }
  }

```

The following methods let you add or remove filters:

::::tabs
:::tab{title="Search"}

- `updateQuery: (searchIdentifier: string, query: string) => void;` - receives the **Search** component identifier and the new query as parameters; triggers a new search request with an updated query.
- `addFilters: (searchIdentifier: string, filters: Array FieldFilterRequestResource>) => void;` - receives as parameters the **Search** component identifier and an array of filters to set; triggers a new search request with the updated filters.
- `clearAllFilters: (searchIdentifier: string) => void;` - clears all filters, including any visual search filters added through an external **Search** component.
- `updateFullTextFilter: (searchIdentifier: string, text: string) => void;` - receives the **Search** component identifier and a new text value as parameters; triggers a new search request with the updated full-text filter.
- `clearFullTextFilter: (searchIdentifier: string) => void;` - receives the **Search** component identifier as parameter; triggers a new search request with an empty full-text filter.
- `getEventSearchIdentifier: (searchIdentifier: string) => string;` - receives the **Search** component identifier as parameter; returns the identifier to check when subscribed to the [*SEARCH_FINISHED event*](https://doc.sitecore.com/ch/en/users/content-hub/external-component-events.html "External component events").
- `activate(searchIdentifier: string): void` - activates the **Search** component with the specified identifier and begins to send search requests.
- `addListener: (searchIdentifier: string, eventName: SearchEvent, listener: SearchEventListener) => DisposeSearchEventListener` - allows external users to add a listener that executes when the event it is listening to occurs. The only event currently available is *BEFORE_SEARCH*. The listeners for this event receive a payload object in the form `{ searchRequest: SearchRequest }` and the code inside the listener modifies this `SearchRequest`. When `false` is returned by any listener, the search request will be canceled. The `addListener` method returns a dispose function that users can call when needed. This dispose method, when called, removes the listener that was added.

:::
:::tab{title="Selection"}

The following methods are available with a **Selection** component:

- `addToSelection: (ids: Array number>, selectionPoolIdentifier: string, subPoolId?: number) => void;` - receives the array of entity `ids` to add, the identifier of the selection pool, and an optional `subPoolId` representing the selection of assets.
- `removeFromSelection: (ids: Array number>, selectionPoolIdentifier: string, subPoolId?: number) => void;` - receives the array of entity `ids` to remove, the identifier of the selection pool, and an optional `subPoolId` representing the selection of assets.
- `clearSelection: (selectionPoolIdentifier: string, subPoolId?: number, definitionNames?: Array string>) => void;` - receives the identifier of the selection pool, an optional `subPoolId` representing the selection of assets, and an optional array of definition names for which to clear the selection. If no definition names are passed, all selections are cleared.

> [!note]
> If you don't provide a **subPoolId** property, the items are added to the standard pool with the identifier **selectionPoolIdentifier**.

:::
:::tab{title="Details"}

This method loads a specified entity:

- `setEntitySource: (identifier: string, entityId: number) => void` - accepts a details component identifier as the first argument and an entity ID as the second argument; it has no return value. If the entity source of a details component is set to `From event`, the specified entity is loaded whenever the `setEntitySource` method is executed from an external component using the component identifier.

The following method is used to reload an entity. If the entity is currently being edited in a details component, the reload does not happen. To force a reload, you can add a second Boolean parameter to the method:

- `reloadEntity: (entityId: number, forceReload?: boolean) => Promise<void>;` - forces the reload of a specific entity when it is being edited if set to `true` as shown in the following example:

    ```text
    context.api.details.reloadEntity(<ENTITY_ID>, true)
    ```

:::
:::tab{title="Notifier"}

The following [notifier events](https://doc.sitecore.com/ch/en/users/content-hub/use-notifier-events.html "Use notifier events") are available:

- `notifySuccess` - receives the text to show in the notification (for example, *Entity saved*).
- `notifyError` - receives the text to show in the notification (for example, *Save failed*).
- `notifyWarning`\- receives the text to show in the notification (for example, *Download partially created*).
- `notifyInfo` - receives the text to show in the notification (for example, *Saved search results changed*).

:::::::
