---
title: "Embedding SDK"
slug: "embedding-sdk"
abstract: "Overview of the Content Hub Embedding SDK with links to how to get started and the API references available."
---
# Embedding SDK

The Embedding SDK allows developers to embed a Content Hub asset picker (**Search** component) directly into their own apps.

From the asset picker, users can browse assets and create and select public links for those assets. Then, when a public link is selected in the asset picker, a callback is triggered with public link details that developers can use in their app.

To simplify setup, Content Hub provides a default asset picker page (`SCAssetConnector`). If you want a customized asset picker, you can [create a page to use as your asset picker](https://doc.sitecore.com/ch/en/developers/cloud-dev/create-an-asset-picker-page.html "Create an asset picker page").

![The Content Hub asset picker embedded in an external app.](https://doc.sitecore.com/api/markdown-image/ch/en/developers/cloud-dev/images/embedding-sdk-asset-picker.png)

> [!note]
> **Before you begin**
> -   [Configure CORS for your external app.](https://doc.sitecore.com/ch/en/developers/cloud-dev/configure-cors-for-your-external-app.html "Configure CORS for your external app")

## Installation

Install the Content Hub Embedding SDK using a supported package manager.

::::tabs
:::tab{title="npm"}
### npm

```bash
npm install @sitecore/contenthub-embedding-sdk --registry=https://npm.sitecore.com/resources/

```

:::
:::tab{title="yarn"}
### Yarn

```bash
yarn add @sitecore/contenthub-embedding-sdk --registry=https://npm.sitecore.com/resources/

```

:::
::::

After installation, the SDK can be imported using ES modules or CommonJS.

## Getting started

The following describes the minimum steps required to embed the Content Hub asset picker and receive asset selection events:

1. Create a container element in your application.
2. Initialize the `ContentHubPageLoader`.
3. Open the embedded Content Hub page.
4. Handle asset selection via callbacks.

### TypeScript example

```typescript
import { ContentHubPageLoader, type ContentHubOptions } from "@sitecore/contenthub-embedding-sdk";

const container = document.getElementById("content-hub-container") as HTMLElement | null;

if (!container) {
  throw new Error("Container element not found");
}

const options: ContentHubOptions = {
  rootElement: container,
  baseUrl: "https://your-content-hub.stylelabs.io",
  pageName: "SCAssetConnector",
  culture: "en-US",
  callbacks: {
    onPublicLinkSelected: ({ entityId, publicLink }) => {
      console.log("Selected asset ID:", entityId);
      console.log("Public link URL:", publicLink);
    },
  },
};

(async () => {
  const loader = new ContentHubPageLoader(options);

  try {
    await loader.open();
    console.log("Content Hub loaded successfully");
  } catch (error) {
    console.error("Failed to load Content Hub:", error);
  }
})();

```

## Configuration

The SDK is configured using the `ContentHubOptions` object passed to `ContentHubPageLoader`.

```typescript
export interface ContentHubOptions {
  rootElement: HTMLElement;
  baseUrl: string;
  pageName?: string;
  culture?: string;
  callbacks?: ContentHubCallbacks;
}

```

| Property | Description |
| --- | --- |
| `rootElement` | DOM element where Content Hub is rendered. |
| `baseUrl` | Base URL of the Content Hub instance. |
| `pageName` | Content Hub page to load. If not specified, defaults to `SCAssetConnector`. Optional. |
| `culture` | UI culture (for example `en-US`). Optional. |
| `callbacks` | Event callbacks for user interactions. Optional. |

## Instance methods

The `ContentHubPageLoader` instance provides the following methods:

| Method | Description |
| --- | --- |
| `open()` | Loads and renders the Content Hub page. Accepts optional configuration options that override constructor options. |
| `dispose()` | Cleans up the Content Hub page rendering and resets internal state. |

## Callbacks

When a user selects a public link in the asset picker, the callback `onPublicLinkSelected` is triggered:

```typescript
export interface ContentHubCallbacks {
  onPublicLinkSelected?: (params: PublicLinkSelectedParams) => void;
}

```

The `onPublicLinkSelected` callback receives the following asset data:

```typescript
export interface PublicLinkSelectedParams {
  title: string;
  alt: string;
  entityId: number;
  publicLinkId: number;
  publicLink: string;
}

```

| Parameter | Description |
| --- | --- |
| `title` | The `title` of the asset associated with the selected public link. |
| `alt` | The **alt text** of the asset associated with the selected public link. |
| `entityId` | The entity ID of the asset associated with the selected public link. |
| `publicLinkId` | The ID of the selected public link. |
| `publicLink` | The URL of the selected public link. |

## Examples

The following examples show how to integrate the SDK into different front-end stacks.

::::tabs
:::tab{title="javascript"}
### JavaScript (ES6)

```javascript
import { ContentHubPageLoader } from "@sitecore/contenthub-embedding-sdk";

ContentHubPageLoader.open({
  rootElement: document.getElementById("content-hub-container"),
  baseUrl: "https://your-content-hub.stylelabs.io",
  pageName: "SCAssetConnector",
  culture: "en-US",
  callbacks: {
    onPublicLinkSelected: (params) => console.log(params),
  },
});

```

:::
:::tab{title="react"}
### React

```javascript
import { useEffect, useRef } from "react";
import { ContentHubPageLoader } from "@sitecore/contenthub-embedding-sdk";

interface Props {
  baseUrl: string;
  onPublicLinkSelected: (params: {
    title: string;
    alt: string;
    entityId: number;
    publicLinkId: number;
    publicLink: string;
  }) => void;
}

export function AssetPicker({ baseUrl, onPublicLinkSelected }: Props) {
  const containerRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    if (!containerRef.current) return;

    const loader = new ContentHubPageLoader({
      rootElement: containerRef.current,
      baseUrl,
      pageName: "SCAssetConnector",
      culture: "en-US",
      callbacks: {
        onPublicLinkSelected: (params) => onPublicLinkSelected(params),
      },
    });

    loader.open().catch(console.error);
    return () => {
      loader.dispose();
    };
  }, [baseUrl, onPublicLinkSelected]);

  return <div ref={containerRef} className="asset-picker-container" />;
}

```

:::
:::tab{title="vue"}
### Vue

```vue
<template>
  <div ref="container" class="asset-picker-container"></div>
</template>

<script>
import { ContentHubPageLoader } from "@sitecore/contenthub-embedding-sdk";

export default {
  props: { baseUrl: { type: String, required: true } },
  async mounted() {
    await new ContentHubPageLoader({
      rootElement: this.$refs.container,
      baseUrl: this.baseUrl,
      pageName: "SCAssetConnector",
      culture: "en-US",
      callbacks: {
        onPublicLinkSelected: (params) => {
          console.log("Asset selected:", params);
          this.$emit("public-link-selected", params);
        },
      },
    }).open();
  },
};
</script>

```

:::
:::tab{title="angular"}
### Angular

```javascript
import { Component, ElementRef, OnInit, ViewChild } from "@angular/core";
import { ContentHubPageLoader, type ContentHubOptions } from "@sitecore/contenthub-embedding-sdk";

interface AssetSelectedParams {
  title: string;
  alt: string;
  entityId: number;
  publicLinkId: number;
  publicLink: string;
}

@Component({
  selector: "app-asset-picker",
  template: `<div #contentHubContainer></div>`,
})
export class AssetPickerComponent implements OnInit {
  @ViewChild("contentHubContainer", { static: true })
  container!: ElementRef<HTMLDivElement>;

  baseUrl = "https://sf-connector.sitecoresandbox.cloud";
  entityId: number | null = null;
  publicUrl: string | null = null;

  async ngOnInit(): Promise<void> {
    const options: ContentHubOptions = {
      rootElement: this.container.nativeElement,
      baseUrl: this.baseUrl,
      pageName: "SCAssetConnector",
      culture: "en-US",
      callbacks: {
        onPublicLinkSelected: (params: AssetSelectedParams) => {
          console.log("Asset selected:", params);
          this.entityId = params.publicLinkId;
          this.publicUrl = params.publicLink;
        },
      },
    };
    await new ContentHubPageLoader(options).open();
  }
}

```

:::
::::

The Content Hub SDK requires a target DOM element to render the picker. For example, you can render the following container `<div>`:

```html
<div class="asset-picker-container"></div>

```

Then apply styling to this container so the picker has an appropriate width, height, and display constraints within your application:

```css
.asset-picker-container {
  width: 600px;
  max-width: 98%;
  height: 70vh;
  margin: 20px auto;
  background: #fff;
  border-radius: 8px;
  box-shadow: 0 4px 24px rgba(0, 0, 0, 0.15);
  position: relative;
}

```

## Troubleshooting

If Content Hub does not load:

- Verify the `baseUrl` is correct.
- Ensure the container element exists and is visible.
- Check the browser console for CORS or network errors.

If the callback is not triggered:

- Confirm `onPublicLinkSelected` is defined.
- Verify user permissions in Content Hub.
- Ensure browser `postMessage` communication is not blocked (for example by browser extensions or CSP).

If you experience TypeScript import issues:

- Use type-only imports when needed:

    ```typescript
    import type { ContentHubOptions } from "@sitecore/contenthub-embedding-sdk";
    ```