Reference

# Configuration

Start with the three required custom-widget attributes. Add presentation options or environment overrides only when the integration needs them.

## Required attributes

| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| `widget-id` | `string` | `-` | Required. The supplied base64 CustomWidget identifier that selects the configured experience. |
| `bundle-url` | `URL` | `-` | Required. The complete widget.js URL supplied for that widget ID. |
| `embed-token` | `JWT` | `-` | Required. Short-lived user token minted by your server through the Access Key API. |

## Common attributes

| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| `theme` | `"light" \| "dark"` | `Widget setting` | Optional host-page override. Omit it to use the configured widget theme. |
| `width` | `CSS length` | `"100%"` | Width of the custom element. |
| `height` | `CSS length` | `"600px"` | Use `auto` for natural bundle height and host-page scrolling. |
| `language` | `language tag` | `Browser language` | Requested language such as `fr-FR`. Regional tags are normalized by the SDK. See [language codes and fallback](#languages). |
| `banner` | `"on" \| "off"` | `"on"` | Set `off` to disable automatic widget-mounted banners. |
| `eager` | `boolean attribute` | `false` | Load immediately instead of waiting until the element becomes visible. |
| `debug` | `boolean attribute` | `false` | Print verbose SDK diagnostics to the browser console. |
| `custom-data` | `JSON string` | `-` | JSON object forwarded to the custom bundle. |
| `retry-label` | `string` | `"Retry"` | Text shown on the SDK error retry button. |

## Language codes and fallback

SDK 1.8.11 accepts these language codes: `en, de, es, fr, it, pt, pl, da, nl, ru, chs, el, ko, cht, th, ja, id, vt, ms, hi, fil, ta, tr, ar, mn, sw`.

Regional tags are normalized: `fr-FR` selects `fr`, `zh-Hans` or `zh-CN` selects `chs`, `zh-Hant` or `zh-TW` selects `cht`, and `vi` selects `vt`. Unsupported or malformed values are not forced; a non-empty invalid value warns once and leaves browser-language fallback to the widget.

This is SDK language selection, not a promise of translated content in every bundle. Ask the setup owner which translations and fallback the supplied widget supports, and record a visible check for each required locale in the [handover](https://docs.returning.ai/broker-integrations/launch-checklist.md#decision-gates).

## Advanced environment overrides

The current SDK already defaults to Returning.AI production hosts. Do not copy these overrides into a normal production embed.

| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| `api-url` | `URL` | `Production widget API` | Optional override for private deployments or a supplied migration configuration. |
| `v2-api-url` | `URL` | `Production V2 API` | Optional override. Production defaults to `https://api-v2.returning.ai`. |
| `domain-key` | `string` | `Production setting` | Optional environment hint. Set it only when Returning.AI supplies a value. |
| `max-retries` | `number` | `3` | Maximum authentication retries. |
| `retry-delay` | `milliseconds` | `500` | Wait between authentication retries. |

## DOM events

| Event | Detail | When it fires |
| --- | --- | --- |
| `rai-authenticated` | `{}` | The embed token was validated and authentication completed. |
| `rai-mounted` | `{}` | The custom bundle mounted into the page. |
| `rai-error` | `{ message, hint?, status? }` | Startup or authentication failed. |
| `rai-logout` | `{}` | The widget session was cleared. |
| `rai-session-expired` | `{ communityId, widgetType, lastAuthError }` | The SDK could not recover the session. Mint and set a fresh embed token. |
| `rai-banner-click` | `Banner event detail` | A widget-mounted banner was clicked. |
| `rai-banner-dismiss` | `Banner event detail` | A widget-mounted banner was dismissed. |

`widget-events.js`

```javascript
const widget = document.querySelector('rai-custom-widget')

widget.addEventListener('rai-authenticated', () => {
  console.log('Widget user authenticated')
})

widget.addEventListener('rai-mounted', () => {
  console.log('Widget bundle mounted')
})

widget.addEventListener('rai-session-expired', async () => {
  const response = await fetch('/api/widget-token')
  const { embedToken } = await response.json()
  widget.setAttribute('embed-token', embedToken)
})

widget.addEventListener('rai-error', (event) => {
  console.error(event.detail.message)
})
```

## JavaScript API

The SDK exposes one global controller after it loads.

`widget-control.js`

```javascript
const sdk = window.ReturningAIWidget

sdk.version
sdk.isAuthenticated()
sdk.getTokenInfo()

await sdk.reload()
await sdk.logout()
```

## Bundle callbacks

Register callbacks on the specific custom element before calling `lockCallbacks()`. Store bundles may also use `callbackFieldOptions` to request signed choices from your backend.

`widget-callbacks.js`

```javascript
const widget = document.querySelector('rai-custom-widget')

widget.registerCallback('storePurchaseSuccess', (purchase) => {
  console.log('Purchase completed', purchase)
})

widget.registerCallback('milestoneCtaClick', ({ buttonName }) => {
  console.log('CTA clicked', buttonName)
})

widget.lockCallbacks()
```

> Sign callback results on your server
>
> Never call a Returning.AI callback-signature endpoint from browser code. Your browser calls your backend; your backend returns the signed result.

## Legacy attributes

These fields remain documented for existing integrations. They are outside the custom-widget starter path.

| Attribute | Type | Default | Description |
| --- | --- | --- | --- |
| `community-id` | `string` | `-` | Required by standard widget tags and standalone banners. Custom widgets use widget-id instead of community-id. |
| `channel-id` | `string` | `-` | Channel widget identifier for older standard-widget integrations. |
| `widget-type` | `string` | `Inferred` | Standard-widget or script-loader type override. |
| `widget-url` | `URL` | `Production frontend` | Hosted frontend URL used by older iframe integrations. |
| `auth-url` | `URL` | `-` | Older token-auth callback. New integrations update embed-token directly. |
| `auto-refresh` | `boolean` | `true` | Automatic refresh for the older auth-url flow. It does not mint Access Key embed tokens. |
| `locale` | `language tag` | `-` | Deprecated alias for language. |
| `storage-prefix` | `string` | `"returning-ai-widget"` | Storage namespace used by older refresh-token flows. |

See [Architecture](https://docs.returning.ai/widget-sdk/architecture.md) for the custom bundle lifecycle.
