> ## Documentation Index
> Fetch the complete documentation index at: https://docs.centaur.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Widget recipes

> Copyable examples for mounting, updating, styling, and removing Centaur widgets.

> [!NOTE]
>
> Widgets are in early access. Sample mode is open to everyone. Live mode is enabled for approved partners in stages.

Each recipe is a complete page you can paste and run on an [allowed site](/integrations/widgets.md#allowed-sites). Replace `YOUR_WIDGET_ID` and use real asset IDs from [Find IDs](/integrations/find-ids.md). To try a recipe without an account, set `mode: 'sample'`, remove `widgetId`, and use assets `900001` and `900002` in place of `1` and `10`.

When you combine recipes, load the SDK once. Call `destroy()` from your page or component teardown so the widget stops its requests.

## Mount a widget

Mount a feed and a positioning card. Each mount returns its own handle.

**Sample**

```html theme={null}
<div id="centaur-feed"></div>
<div id="centaur-positioning"></div>
<script src="https://widgets.centaur.io/v1/sdk.js" crossorigin="anonymous"></script>
<script>
const widget = CentaurWidgets.v1.mount(document.getElementById('centaur-feed'), {
  kind: 'feed', mode: 'sample', selection: { assetIds: [900001] }
});
const positioning = CentaurWidgets.v1.mount(document.getElementById('centaur-positioning'), {
  kind: 'positioning', mode: 'sample', selection: { assetId: 900001 }
});
// Call widget.destroy() and positioning.destroy() when you remove their containers.
</script>
```

**Live**

```html theme={null}
<div id="centaur-feed"></div>
<div id="centaur-positioning"></div>
<script src="https://widgets.centaur.io/v1/sdk.js" crossorigin="anonymous"></script>
<script>
const widget = CentaurWidgets.v1.mount(document.getElementById('centaur-feed'), {
  kind: 'feed', mode: 'live', widgetId: 'YOUR_WIDGET_ID', selection: { assetIds: [1] }
});
const positioning = CentaurWidgets.v1.mount(document.getElementById('centaur-positioning'), {
  kind: 'positioning', mode: 'live', widgetId: 'YOUR_WIDGET_ID', selection: { assetId: 1 }
});
// Call widget.destroy() and positioning.destroy() when you remove their containers.
</script>
```

## Follow your page's asset

Call `onAssetPageChange` from your router with the Centaur asset ID of the page the visitor opened. The widget switches assets without remounting and ignores responses for the old asset. Call `onLeaveAssetPages` when the visitor leaves your asset pages.

`update` replaces the whole selection, so pass everything you want to keep. To go back to the general feed, call `widget.update({ selection: {} })`.

```html theme={null}
<div id="centaur-feed"></div>
<script src="https://widgets.centaur.io/v1/sdk.js" crossorigin="anonymous"></script>
<script>
const widget = CentaurWidgets.v1.mount(document.getElementById('centaur-feed'), {
  kind: 'feed', mode: 'live', widgetId: 'YOUR_WIDGET_ID', selection: { assetIds: [1] }
});
function onAssetPageChange(assetId) {
  widget.update({ selection: { assetIds: [assetId] } });
}
// onAssetPageChange(10); // Your router supplies the next page's asset ID.
function onLeaveAssetPages() { widget.destroy(); }
</script>
```

## Style it and link to your pages

Set `appearance` to match your page. `theme: 'system'` follows the visitor's operating system. `assetUrls` sends asset links to your own asset pages. A positioning card takes a single `viewActivityUrl` instead and has no height option.

```html theme={null}
<div id="centaur-feed"></div>
<script src="https://widgets.centaur.io/v1/sdk.js" crossorigin="anonymous"></script>
<script>
const widget = CentaurWidgets.v1.mount(document.getElementById('centaur-feed'), {
  kind: 'feed', mode: 'live', widgetId: 'YOUR_WIDGET_ID', selection: { assetIds: [1] },
  appearance: { theme: 'dark', width: '100%', height: 420 },
  assetUrls: { 1: '/assets/btc' }
});
</script>
```

If your app uses client-side routing, hand asset clicks to your router:

```js theme={null}
widget.update({
  onAssetNavigate({ url }) {
    yourRouter.navigate(url);
    // Return false instead to keep normal browser navigation.
  }
});
```

## Use it in React

Copy this component into your app. It loads the SDK once, follows `assetId`, and cleans up on unmount, including under StrictMode.

Save this as `load-centaur.js`:

```js theme={null}
let loading;
export function loadCentaur() {
  if (window.CentaurWidgets?.v1) return Promise.resolve(window.CentaurWidgets.v1);
  loading ??= new Promise((resolve, reject) => {
    const script = document.createElement('script');
    script.src = 'https://widgets.centaur.io/v1/sdk.js';
    script.crossOrigin = 'anonymous';
    script.onload = () => {
      if (window.CentaurWidgets?.v1) resolve(window.CentaurWidgets.v1);
      else failed();
    };
    function failed() {
      loading = undefined;
      script.remove();
      reject(new Error('The Centaur SDK could not load.'));
    }
    script.onerror = failed;
    document.head.append(script);
  });
  return loading;
}
```

```jsx theme={null}
'use client';
import { useEffect, useRef, useState } from 'react';
import { loadCentaur } from './load-centaur.js';

export function AssetFeed({ assetId, widgetId }) {
  const container = useRef(null);
  const widget = useRef(null);
  const currentAsset = useRef(assetId);
  const [error, setError] = useState('');

  useEffect(() => {
    currentAsset.current = assetId;
    widget.current?.update({ selection: { assetIds: [assetId] } });
  }, [assetId]);

  useEffect(() => {
    let active = true;
    setError('');
    loadCentaur().then((sdk) => {
      if (!active) return;
      widget.current = sdk.mount(container.current, {
        kind: 'feed', mode: 'live', widgetId,
        selection: { assetIds: [currentAsset.current] }
      });
    }).catch((error) => { if (active) setError(error.message); });
    return () => {
      active = false;
      widget.current?.destroy();
      widget.current = null;
    };
  }, [widgetId]);

  return <>{error && <p role="alert">{error}</p>}<div ref={container} /></>;
}
// Pass your widgetId and verified assetId 1, then 10.
```


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.