How the Widget SDK isolates styles, authenticates users, and communicates between your page and the widget iframe.
Each widget element creates a closed Shadow Root. This means the widget's internal DOM and styles are completely encapsulated - your page's CSS cannot leak into the widget, and the widget's styles cannot affect your page.
This makes the SDK safe to use alongside any CSS framework (Tailwind, Bootstrap, Material UI, etc.) without conflicts. The closed mode also prevents external JavaScript from accessing the Shadow Root via element.shadowRoot, providing an additional layer of isolation.
Customer page DOM
└── <div id="returning-ai-widget-{id}">
└── <rai-widget>
└── Shadow Root [closed]
├── <style> ← CSS scoped here
├── <div class="rai-loader">
├── <div class="rai-error">
└── <iframe> ← widget contentWhen the widget element connects to the DOM, it checks for the auth-url attribute. If present, the SDK initiates the token authentication flow:
postMessage so the widget can make authenticated API calls.If auth-url is not set, the widget loads using attribute authentication (reading data-* attributes from the element) and skips the token fetch in steps 2–3.
The SDK manages two tokens with different storage strategies to balance security and user experience.
| Token | Storage | Lifetime | Purpose |
|---|---|---|---|
| Access token | Memory only | ~5 minutes | Short-lived credential sent to the iframe for API calls. Never written to disk. |
| Refresh token | localStorage | 7 days | Used to obtain new access tokens without re-authenticating the user. |
The SDK and the widget iframe communicate via window.postMessage. All messages use a typed type field for routing.
| Type | Payload | Description |
|---|---|---|
| RETURNINGAI_WIDGET_TOKEN | { token, widgetId } | Delivers the access token to the iframe after authentication. |
| RETURNINGAI_WIDGET_REFRESH | { token, widgetId } | Sends a refreshed access token before the current one expires. |
| RETURNINGAI_WIDGET_LOGOUT | { widgetId } | Instructs the iframe to clear its session state. |
| Type | Payload | Description |
|---|---|---|
| RETURNINGAI_WIDGET_REQUEST_TOKEN | { widgetId } | Iframe requests an access token (sent on iframe load). |
| RETURNINGAI_WIDGET_READY | { widgetId } | Widget has finished initialising and is interactive. |
| RETURNINGAI_WIDGET_HEIGHT | { height } | Reports the widget content height for auto-sizing. |
| RETURNINGAI_WIDGET_ERROR | { message, code? } | Reports an error from within the iframe. |
The SDK requires custom elements v1 and Shadow DOM v1 support. All modern browsers are supported.
| Browser | Minimum Version |
|---|---|
| Chrome | 67+ |
| Firefox | 63+ |
| Safari | 13+ |
| Edge | 79+ (Chromium) |
| Opera | 54+ |