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

# Web Widget Deployment

> Embed an AI voice and chat widget on any website with a single script tag.

The Web Widget deployment embeds an interactive AI assistant directly into your website. Visitors can type messages, speak via microphone, and hear voice responses — all from a floating widget that loads with a single script tag. Voice input and output are optional; the widget works as a text-only chat by default.

<Info>
  Voice capabilities (microphone input and spoken responses) are optional. You can deploy a text-only chat widget by skipping the Voice Input and Voice Output steps during configuration.
</Info>

<Tip>
  Use [Listen](/assistants/configuration/listen) when enabling microphone input and [Speak](/assistants/configuration/speak) when enabling spoken responses for the widget.
</Tip>

## Creating a Web Widget Deployment

Navigate to your assistant, click **Configure Assistant**, then select **Deployments** from the sidebar. Click **Add Deployment** and choose **Web Widget**.

The web widget wizard walks you through four steps:

<Steps>
  <Step title="Experience">
    Define the greeting, quickstart questions, and session behaviour.

    **Required fields:**

    * **Greeting** — Welcome message displayed when the widget opens. Describe your agent so users know how to interact with it

    **Quickstart Questions:**

    * **Quickstart Questions** — Pre-configured questions displayed as clickable buttons below the greeting. Users can tap one to start a conversation instantly, or type their own query

    **Advanced settings** (expand to configure):

    * **Error Message** — Message shown when an unexpected error occurs
    * **Idle Silence Timeout** — Duration of silence before Rapida prompts the user (3000-10000ms, default: 30000ms)
    * **Idle Timeout Backoff** — How many times the idle timeout multiplies before ending the session (0-5, default: 2)
    * **Idle Message** — Message spoken/shown when the user hasn't responded (default: "Are you there?")
    * **Maximum Session Duration** — Hard limit before the session is automatically ended (3-15 minutes, default: 5 min)
  </Step>

  <Step title="Voice Input (Speech-to-Text) — Optional">
    Enable microphone-based voice input for the widget. Users can speak instead of typing.

    **If enabled:**

    * **STT Provider** — Deepgram, AssemblyAI, Google, Azure, OpenAI Whisper, AWS Transcribe, Cartesia, Rev.ai, Speechmatics, Sarvam, Groq, or Nvidia
    * **Model** — Provider-specific transcription model
    * **Language** — Primary transcription language
    * **Encoding** — Audio encoding format
    * **Sample Rate** — Audio sample rate

    **Advanced settings** (expand to configure):

    * **Voice Activity Detection (VAD)** — Silero VAD with configurable threshold (0.0-1.0, default: 0.8)
    * **Background Noise Removal** — RNNoise for removing ambient noise before transcription
    * **End of Speech Detection** — Silence-based EOS with configurable timeout (default: 1000ms)

    <Tip>
      Click **Skip** to deploy a text-only widget without voice input. You can enable it later by editing the deployment.
    </Tip>
  </Step>

  <Step title="Voice Output (Text-to-Speech) — Optional">
    Enable spoken audio responses from the assistant. The assistant's text responses will be read aloud through the browser.

    **If enabled:**

    * **TTS Provider** — ElevenLabs, Deepgram, Azure, Google, OpenAI, AWS Polly, Cartesia, Resemble, Rime, Sarvam, Neuphonic, MiniMax, Groq, Speechmatics, or Nvidia
    * **Model** — Provider-specific voice model
    * **Language** — Output speech language
    * **Voice ID** — The specific voice from your TTS provider

    **Advanced settings** (expand to configure):

    * **Pronunciation Dictionaries** — Custom pronunciation for domain-specific terms, names, and acronyms
    * **Conjunction Boundaries** — Natural pause points at conjunctions for more human-like speech
    * **Pause Duration** — Length of pause at conjunction boundaries (100-300ms, default: 240ms)

    <Tip>
      Click **Skip** to deploy without voice output. Text responses will still appear in the chat. You can enable voice output later.
    </Tip>
  </Step>

  <Step title="Features">
    Enable additional content sections available in the web widget beyond the chat interface.

    **Available sections:**

    * **Help Center / Q\&A Listing** — Display a searchable FAQ section alongside the chat, powered by your knowledge base
    * **Product Catalog** — Show product listings and details within the widget
    * **Blog Post / Articles** — Surface blog posts and articles for self-service browsing

    Click **Deploy Web Widget** to save and activate the deployment.
  </Step>
</Steps>

## Embedding the Widget

After deployment, Rapida generates a pre-built widget script (`app.min.js`) hosted on the Rapida CDN. You configure it by setting `window.chatbotConfig` before the script loads.

### Quick Start

Add this to any page on your website:

```html theme={null}
<script>
  window.chatbotConfig = {
    assistant_id: "YOUR_ASSISTANT_ID",
    token: "YOUR_PROJECT_CREDENTIAL_KEY",
  };
</script>
<script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
```

The default configuration renders a floating launcher in the bottom-right corner of the page. Clicking it opens the chat window with your assistant's greeting and quickstart questions.

<Note>
  Replace `YOUR_ASSISTANT_ID` with your assistant's ID (found on the assistant overview page) and `YOUR_PROJECT_CREDENTIAL_KEY` with your project credential key from the [credential vault](/credential/rapida-credentials).
</Note>

### Installation Options

Use the latest hosted widget script:

```html theme={null}
<script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
```

Pin to a specific widget build when you need controlled rollout:

```html theme={null}
<script defer src="https://cdn-01.rapida.ai/public/scripts/v1.2.0/app.min.js"></script>
```

You can also install the package from npm and serve the built `dist/app.min.js` file from your own application or CDN:

```bash theme={null}
npm install @rapidaai/web-widget
```

### Configuration Options

Set `window.chatbotConfig` before loading the widget script. The widget has two configuration layers:

* **Rapida layer** — connection, authentication, assistant version, user identity, language, and debug logging
* **UI layer** — native IBM AI Chat configuration exposed directly on `window.chatbotConfig`

Rapida always owns `messaging.customSendMessage` because text messages must go through the Rapida SDK. Rapida also appends its audio controls through `renderWriteableElements.afterInputElement`; if you provide your own `afterInputElement`, it is preserved and Rapida audio controls are appended after it.

Use the sectioned config shape below. Do not use a `carbon` config key.

```html theme={null}
<script>
  window.chatbotConfig = {
    // Required
    assistant_id: "YOUR_ASSISTANT_ID",
    token: "YOUR_PROJECT_CREDENTIAL_KEY",

    // Optional: target a specific assistant version
    assistant_version: "VERSION_ID",

    // Optional: custom API base URL (for self-hosted deployments)
    api_base: "https://assistant-01.in.rapida.ai",

    // Optional: language for the widget UI (default: "en", auto-detects from <html lang="">)
    language: "en",

    // Optional: enable debug logging in the browser console
    debug: false,

    // Optional: user identification
    user: {
      name: "Jane Doe",
      user_id: "user-123",
      meta: {
        plan: "enterprise",
        source: "pricing-page",
      },
    },

    // Optional: assistant identity
    name: "Support Bot",
    logo_url: "https://example.com/avatar.png",

    // Optional: layout
    layout: {
      mode: "floating",          // "floating" | "docked-right" | "docked-left" | "inline"
      position: "bottom-right",  // "bottom-right" | "bottom-left" | "top-right" | "top-left"
      corners: "square",
      showFrame: true,
      customProperties: {
        width: "420px",
        height: "640px",
      },
    },

    // Optional: theme
    theme: {
      mode: "light",             // "light" | "dark" | "system"
      injectTheme: "g10",        // "white" | "g10" | "g90" | "g100"
    },

    // Optional: chat UI sections
    aiEnabled: false,
    header: {
      title: "Support Bot",
      showAiLabel: false,
      minimizeButtonIconType: "side-panel-right",
    },
    launcher: {
      isOn: true,
    },
    history: {
      isOn: false,
    },
    messaging: {
      messageTimeoutSecs: 150,
      messageLoadingIndicatorTimeoutSecs: 1,
    },
  };
</script>
<script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
```

### Required Rapida Options

| Property       | Type     | Default  | Description                                                                         |
| -------------- | -------- | -------- | ----------------------------------------------------------------------------------- |
| `assistant_id` | `string` | required | Rapida assistant ID.                                                                |
| `token`        | `string` | required | Project credential key from the [credential vault](/credential/rapida-credentials). |

### Rapida Options

| Property            | Type                     | Default                             | Description                                                                        |
| ------------------- | ------------------------ | ----------------------------------- | ---------------------------------------------------------------------------------- |
| `api_base`          | `string`                 | `https://assistant-01.in.rapida.ai` | Rapida API base URL. Use this for self-hosted or environment-specific backends.    |
| `assistant_version` | `string`                 | latest version                      | Assistant version to load when the backend supports versioned deployments.         |
| `user.name`         | `string`                 | `Guest`                             | Display name for the current user.                                                 |
| `user.user_id`      | `string`                 | generated and stored locally        | Stable user ID. Provide one if your host app already has an authenticated user ID. |
| `user.meta`         | `Record<string, string>` | `{ source: "web plugin" }`          | Extra metadata sent to Rapida with the user session.                               |
| `language`          | `string`                 | host page language or `en`          | Locale passed to the UI. The widget also watches the `<html lang>` attribute.      |
| `debug`             | `boolean`                | `false`                             | Enables additional client logging and passes debug mode to the UI layer.           |
| `name`              | `string`                 | deployment name                     | Friendly assistant name. Used as the default `assistantName` and `header.title`.   |
| `logo_url`          | `string`                 | default assistant avatar            | Assistant avatar URL. Used as the default `assistantAvatarUrl`.                    |

### Theme Options

Use `theme` for all theme-level options.

| Property            | Type                                  | Default                   | Description                                                                                                                                                                   |
| ------------------- | ------------------------------------- | ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `theme.mode`        | `"light" \| "dark" \| "system"`       | `"light"`                 | Widget color mode. `dark` defaults the UI token injection to `g100`; `light` defaults it to `g10`; `system` lets the host or system decide unless `theme.injectTheme` is set. |
| `theme.injectTheme` | `"white" \| "g10" \| "g90" \| "g100"` | derived from `theme.mode` | UI theme token injected into the chat shadow DOM. Set this when the host page does not already provide compatible theme tokens.                                               |
| `theme.color`       | `string`                              | none                      | Legacy primary brand color. Prefer `layout.customProperties` for current UI customization.                                                                                    |

### Layout Options

`layout` can be a string for old embeds or an object for the current sectioned config.

```js theme={null}
window.chatbotConfig = {
  layout: {
    mode: "floating",
    position: "bottom-right",
    corners: "square",
    showFrame: true,
    customProperties: {
      width: "420px",
      height: "640px",
    },
  },
};
```

| Property                    | Type                                                           | Default                | Description                                                                                                    |
| --------------------------- | -------------------------------------------------------------- | ---------------------- | -------------------------------------------------------------------------------------------------------------- |
| `layout`                    | `string \| object`                                             | `"floating"`           | Widget layout. String values are still supported: `"floating"`, `"docked-right"`, `"docked-left"`, `"inline"`. |
| `layout.mode`               | `"floating" \| "docked-right" \| "docked-left" \| "inline"`    | `"floating"`           | Rapida placement mode.                                                                                         |
| `layout.position`           | `"bottom-right" \| "bottom-left" \| "top-right" \| "top-left"` | `"bottom-right"`       | Floating launcher and panel position.                                                                          |
| `layout.showLauncher`       | `boolean`                                                      | `true` for floating    | Legacy launcher shortcut inside `layout`. Prefer `launcher.isOn`.                                              |
| `layout.showFrame`          | `boolean`                                                      | `true`                 | Keeps the native border and shadow frame.                                                                      |
| `layout.hasContentMaxWidth` | `boolean`                                                      | UI default             | Constrains message content to the UI max width.                                                                |
| `layout.corners`            | `"round" \| "square" \| object`                                | `"square"`             | Corner style. Use a string for all corners or an object for per-corner control.                                |
| `layout.customProperties`   | `Record<string, string>`                                       | generated for floating | CSS variable overrides for the chat UI. Values are raw CSS strings.                                            |

Per-corner `layout.corners` object:

| Property     | Type                  | Description                              |
| ------------ | --------------------- | ---------------------------------------- |
| `startStart` | `"round" \| "square"` | Top-left in LTR, top-right in RTL.       |
| `startEnd`   | `"round" \| "square"` | Top-right in LTR, top-left in RTL.       |
| `endStart`   | `"round" \| "square"` | Bottom-left in LTR, bottom-right in RTL. |
| `endEnd`     | `"round" \| "square"` | Bottom-right in LTR, bottom-left in RTL. |

Supported `layout.customProperties` keys:

| Key                                                 | Description                                   |
| --------------------------------------------------- | --------------------------------------------- |
| `height`                                            | Floating chat height.                         |
| `max-height`                                        | Floating chat maximum height.                 |
| `width`                                             | Floating chat width.                          |
| `min-height`                                        | Floating chat minimum height.                 |
| `max-width`                                         | Floating chat maximum width.                  |
| `z-index`                                           | Floating chat z-index.                        |
| `bottom-position`                                   | Floating panel distance from viewport bottom. |
| `right-position`                                    | Floating panel distance from viewport right.  |
| `top-position`                                      | Floating panel distance from viewport top.    |
| `left-position`                                     | Floating panel distance from viewport left.   |
| `launcher-default-size`                             | Launcher button size.                         |
| `launcher-position-bottom`                          | Launcher distance from viewport bottom.       |
| `launcher-position-right`                           | Launcher distance from viewport right.        |
| `launcher-extended-width`                           | Expanded launcher width.                      |
| `messages-max-width`                                | Maximum width for message content.            |
| `messages-min-width`                                | Minimum width for message content.            |
| `workspace-min-width`                               | Minimum width for workspace panels.           |
| `card-max-width`                                    | Maximum width for card responses.             |
| `launcher-color-background`                         | Launcher background color.                    |
| `launcher-color-avatar`                             | Launcher icon/avatar color.                   |
| `launcher-color-background-hover`                   | Launcher hover background.                    |
| `launcher-color-background-active`                  | Launcher active background.                   |
| `launcher-color-focus-border`                       | Launcher focus border color.                  |
| `launcher-mobile-color-text`                        | Mobile launcher text color.                   |
| `launcher-expanded-message-color-text`              | Expanded launcher text color.                 |
| `launcher-expanded-message-color-background`        | Expanded launcher background.                 |
| `launcher-expanded-message-color-background-hover`  | Expanded launcher hover background.           |
| `launcher-expanded-message-color-background-active` | Expanded launcher active background.          |
| `launcher-expanded-message-color-focus-border`      | Expanded launcher focus border color.         |
| `unread-indicator-color-background`                 | Unread indicator background color.            |
| `unread-indicator-color-text`                       | Unread indicator text color.                  |

### Header Options

| Property                           | Type                                                                                    | Default                            | Description                                                                                                         |
| ---------------------------------- | --------------------------------------------------------------------------------------- | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------- |
| `header.isOn`                      | `boolean`                                                                               | `true`                             | Enables the native chat header. Set `false` for a fully embedded or fullscreen experience with your own app header. |
| `header.title`                     | `string`                                                                                | `name` or deployment name          | Header title. Set `""` to remove the visible title.                                                                 |
| `header.name`                      | `string`                                                                                | UI default                         | Secondary name shown after the title. Set `""` to remove it.                                                        |
| `header.minimizeButtonIconType`    | `"close" \| "minimize" \| "side-panel-left" \| "side-panel-right" \| "side-panel-down"` | side-panel icon based on dock side | Icon for the close/minimize button.                                                                                 |
| `header.hideMinimizeButton`        | `boolean`                                                                               | `false`                            | Hides the close/minimize button.                                                                                    |
| `header.showRestartButton`         | `boolean`                                                                               | `false`                            | Shows the restart conversation button.                                                                              |
| `header.menuOptions`               | `Array<{ text: string }>`                                                               | none                               | Custom menu options in the header menu.                                                                             |
| `header.showAiLabel`               | `boolean`                                                                               | `false`                            | Shows the AI label in the header. Disabled by default.                                                              |
| `header.hideDefaultAiLabelContent` | `boolean`                                                                               | `true`                             | Hides the default AI label popover content.                                                                         |
| `header.hasContentMaxWidth`        | `boolean`                                                                               | `false`                            | Constrains the header to the message content width.                                                                 |
| `header.actions`                   | `ToolbarAction[]`                                                                       | none                               | Custom header toolbar actions.                                                                                      |

### Launcher Options

| Property                             | Type      | Default                                        | Description                                             |
| ------------------------------------ | --------- | ---------------------------------------------- | ------------------------------------------------------- |
| `launcher.isOn`                      | `boolean` | `true` for floating, `false` for docked/inline | Shows the floating launcher button.                     |
| `launcher.showUnreadIndicator`       | `boolean` | UI default                                     | Shows the unread dot on the launcher.                   |
| `launcher.mobile.avatarUrlOverride`  | `string`  | none                                           | Custom mobile launcher avatar or icon URL.              |
| `launcher.mobile.isOn`               | `boolean` | `false`                                        | Deprecated expanded call-to-action launcher state.      |
| `launcher.mobile.title`              | `string`  | translated default                             | Deprecated expanded launcher title.                     |
| `launcher.mobile.timeToExpand`       | `number`  | `15`                                           | Deprecated delay before launcher expansion, in seconds. |
| `launcher.desktop.avatarUrlOverride` | `string`  | none                                           | Custom desktop launcher avatar or icon URL.             |
| `launcher.desktop.isOn`              | `boolean` | `false`                                        | Deprecated expanded call-to-action launcher state.      |
| `launcher.desktop.title`             | `string`  | translated default                             | Deprecated expanded launcher title.                     |
| `launcher.desktop.timeToExpand`      | `number`  | `15`                                           | Deprecated delay before launcher expansion, in seconds. |

### Messaging Options

| Property                                       | Type      | Default       | Description                                                                                              |
| ---------------------------------------------- | --------- | ------------- | -------------------------------------------------------------------------------------------------------- |
| `messaging.skipWelcome`                        | `boolean` | UI default    | Starts new conversations without requesting a welcome message.                                           |
| `messaging.messageTimeoutSecs`                 | `number`  | `150`         | Message timeout in seconds. Use `0` to disable automatic timeout.                                        |
| `messaging.messageLoadingIndicatorTimeoutSecs` | `number`  | `1`           | Delay before the UI shows a loading indicator. Use `0` to prevent the UI from showing one automatically. |
| `messaging.customSendMessage`                  | function  | Rapida bridge | Reserved. Rapida overwrites this so text is sent through the Rapida SDK.                                 |
| `messaging.customLoadHistory`                  | function  | none          | Optional function that returns native history items for the UI.                                          |
| `messaging.showStopButtonImmediately`          | `boolean` | `false`       | Shows the stop button as soon as a message request starts.                                               |

### Other UI Options

| Property                                 | Type                                             | Default                                        | Description                                                                                        |
| ---------------------------------------- | ------------------------------------------------ | ---------------------------------------------- | -------------------------------------------------------------------------------------------------- |
| `history.isOn`                           | `boolean`                                        | `false`                                        | Enables the native history panel.                                                                  |
| `history.showMobileMenu`                 | `boolean`                                        | `true`                                         | Shows mobile header menu options for new chat and view chats.                                      |
| `history.startClosed`                    | `boolean`                                        | `false`                                        | Starts history closed and preserves open/closed state across responsive mode changes.              |
| `input.maxInputCharacters`               | `number`                                         | `10000`                                        | Maximum characters allowed in the text input.                                                      |
| `input.isVisible`                        | `boolean`                                        | `true`                                         | Shows or hides the main input surface.                                                             |
| `input.isDisabled`                       | `boolean`                                        | `false`                                        | Disables text input. Rapida also disables text input while audio mode is active.                   |
| `homescreen.isOn`                        | `boolean`                                        | `false`                                        | Enables the native home screen before chat.                                                        |
| `homescreen.greeting`                    | `string`                                         | none                                           | Greeting text on the home screen.                                                                  |
| `homescreen.starters.isOn`               | `boolean`                                        | UI default                                     | Shows starter buttons.                                                                             |
| `homescreen.starters.buttons`            | `Array<{ label: string; isSelected?: boolean }>` | none                                           | Starter utterances displayed as buttons.                                                           |
| `homescreen.customContentOnly`           | `boolean`                                        | `false`                                        | Hides the built-in greeting and starters so custom content can own the home screen.                |
| `homescreen.disableReturn`               | `boolean`                                        | `false`                                        | Prevents returning to the home screen after a user has sent a message.                             |
| `disclaimer.isOn`                        | `boolean`                                        | `false`                                        | Shows a disclaimer screen before chat.                                                             |
| `disclaimer.disclaimerHTML`              | `string`                                         | required when enabled                          | HTML content for the disclaimer. If this changes after acceptance, the user must accept again.     |
| `aiEnabled`                              | `boolean`                                        | `false`                                        | Enables AI visual styling. The widget disables this by default.                                    |
| `assistantName`                          | `string`                                         | `name` or deployment name                      | Assistant name used by the UI for accessibility, errors, and defaults.                             |
| `assistantAvatarUrl`                     | `string`                                         | `logo_url`                                     | Assistant avatar URL used by native messages.                                                      |
| `locale`                                 | `string`                                         | `language`                                     | UI locale. Prefer `language` unless you need to override only the UI.                              |
| `namespace`                              | `string`                                         | `rapida-chat`                                  | Namespace for DOM IDs, storage keys, and multi-instance isolation. Must be 30 characters or fewer. |
| `openChatByDefault`                      | `boolean`                                        | `true` for docked/inline, `false` for floating | Opens the chat when it first renders.                                                              |
| `shouldSanitizeHTML`                     | `boolean`                                        | `true`                                         | Sanitizes assistant HTML before rendering.                                                         |
| `shouldTakeFocusIfOpensAutomatically`    | `boolean`                                        | `false`                                        | Moves focus into the chat when it opens on page load.                                              |
| `disableCustomElementMobileEnhancements` | `boolean`                                        | `false`                                        | Disables mobile enhancements that can conflict with custom element embedding.                      |
| `isReadonly`                             | `boolean`                                        | `false`                                        | Puts the chat in read-only mode for viewing old conversations.                                     |
| `persistFeedback`                        | `boolean`                                        | `false`                                        | Keeps feedback controls visible beyond the latest message.                                         |
| `strings`                                | partial language pack                            | UI defaults                                    | Overrides built-in UI strings.                                                                     |
| `injectCarbonTheme`                      | `"white" \| "g10" \| "g90" \| "g100"`            | derived from `theme`                           | Raw UI prop. Prefer `theme.injectTheme`.                                                           |
| `onError`                                | function                                         | none                                           | Called for catastrophic UI errors.                                                                 |

### Upload Options

File upload is experimental in the underlying UI.

| Property                  | Type      | Default        | Description                                                                    |
| ------------------------- | --------- | -------------- | ------------------------------------------------------------------------------ |
| `upload.is_on`            | `boolean` | `false`        | Enables the attachment button. Requires `upload.onFileUpload`.                 |
| `upload.accept`           | `string`  | all file types | Accepted MIME types or extensions, same format as the HTML `accept` attribute. |
| `upload.maxFileSizeBytes` | `number`  | none           | Client-side maximum file size.                                                 |
| `upload.maxFiles`         | `number`  | none           | Maximum number of pending files.                                               |
| `upload.onFileUpload`     | function  | none           | Called once per selected file. Return structured data for the pending message. |

### Keyboard Shortcut Options

Keyboard shortcut configuration is experimental in the underlying UI.

| Property                                               | Type      | Default | Description                                      |
| ------------------------------------------------------ | --------- | ------- | ------------------------------------------------ |
| `keyboardShortcuts.messageFocusToggle.is_on`           | `boolean` | `true`  | Enables the message/input focus toggle shortcut. |
| `keyboardShortcuts.messageFocusToggle.key`             | `string`  | `"F6"`  | Primary shortcut key.                            |
| `keyboardShortcuts.messageFocusToggle.modifiers.alt`   | `boolean` | `false` | Requires Alt.                                    |
| `keyboardShortcuts.messageFocusToggle.modifiers.shift` | `boolean` | `false` | Requires Shift.                                  |
| `keyboardShortcuts.messageFocusToggle.modifiers.ctrl`  | `boolean` | `false` | Requires Control.                                |
| `keyboardShortcuts.messageFocusToggle.modifiers.meta`  | `boolean` | `false` | Requires Command/Meta.                           |

### Service Desk Options

These are advanced native UI options for human-agent handoff integrations.

| Property                                 | Type      | Default    | Description                                                                                         |
| ---------------------------------------- | --------- | ---------- | --------------------------------------------------------------------------------------------------- |
| `serviceDeskFactory`                     | function  | none       | Factory that creates a service desk integration instance.                                           |
| `serviceDesk.availabilityTimeoutSeconds` | `number`  | UI default | Timeout used while checking whether human agents are available.                                     |
| `serviceDesk.skipConnectHumanAgentCard`  | `boolean` | `false`    | Auto-connects to an available agent after a connect-to-agent response while still showing the card. |
| `serviceDesk.agentJoinTimeoutSeconds`    | `number`  | none       | Timeout while waiting for an agent to join after one is requested.                                  |
| `serviceDesk.allowReconnect`             | `boolean` | `true`     | Attempts to reconnect the user to a prior human-agent conversation when supported.                  |

### Render And Lifecycle Hooks

| Property                           | Type     | Description                                                                                                          |
| ---------------------------------- | -------- | -------------------------------------------------------------------------------------------------------------------- |
| `onBeforeRender(instance)`         | function | Called before the UI renders. Rapida uses this internally, then calls your handler.                                  |
| `onAfterRender(instance)`          | function | Called after the UI renders.                                                                                         |
| `onViewPreChange(event, instance)` | function | Called before the chat opens or closes. Can return a promise to delay the view change.                               |
| `onViewChange(event, instance)`    | function | Called after the chat opens or closes. Rapida uses this to track docked/inline shell state, then calls your handler. |
| `renderUserDefinedResponse`        | function | Renders custom `user_defined` response items.                                                                        |
| `renderCustomMessageFooter`        | function | Renders custom message footers.                                                                                      |
| `renderWriteableElements`          | object   | Renders writable slots. Rapida merges `afterInputElement` with its audio controls.                                   |

### Layout Modes

#### Floating

A fixed-position panel with a launcher button. Click the launcher to open or close the chat.

```js theme={null}
window.chatbotConfig = {
  layout: {
    mode: "floating",
    position: "bottom-right",
  },
  launcher: {
    isOn: true,
  },
};
```

#### Docked

A side panel fixed to the viewport. When open, it pushes page content to make room.

```js theme={null}
window.chatbotConfig = {
  layout: {
    mode: "docked-right", // or "docked-left"
  },
};
```

#### Inline

The widget flows with the page content. Place the `<div id="rapida-chat-app">` where you want it to render.

```html theme={null}
<div id="rapida-chat-app"></div>
<script>
  window.chatbotConfig = {
    assistant_id: "YOUR_ASSISTANT_ID",
    token: "YOUR_PROJECT_CREDENTIAL_KEY",
    layout: {
      mode: "inline",
    },
  };
</script>
<script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
```

### Legacy Shortcuts

These remain supported for old embeds. Prefer the sectioned config above for new usage.

| Property                 | Replacement                        |
| ------------------------ | ---------------------------------- |
| `layout: "floating"`     | `layout: { mode: "floating" }`     |
| `layout: "docked-right"` | `layout: { mode: "docked-right" }` |
| `layout: "docked-left"`  | `layout: { mode: "docked-left" }`  |
| `layout: "inline"`       | `layout: { mode: "inline" }`       |
| `position`               | `layout.position`                  |
| `showLauncher`           | `launcher.isOn`                    |

### Full HTML Example

```html theme={null}
<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My Website</title>
</head>
<body>
  <h1>Welcome to my website</h1>

  <!-- Rapida Web Widget Configuration -->
  <script>
    window.chatbotConfig = {
      assistant_id: "YOUR_ASSISTANT_ID",
      token: "YOUR_PROJECT_CREDENTIAL_KEY",
      user: {
        name: "Jane Doe",
        user_id: "website-visitor-001",
        meta: {
          source: "marketing-site",
          page: window.location.pathname,
        },
      },
      name: "Support Bot",
      logo_url: "https://example.com/avatar.png",
      layout: {
        mode: "floating",
        position: "bottom-right",
        customProperties: {
          width: "420px",
          height: "640px",
        },
      },
      theme: {
        mode: "light",
        injectTheme: "g10",
      },
      header: {
        title: "Support Bot",
        showAiLabel: false,
      },
      launcher: {
        isOn: true,
      },
    };
  </script>
  <script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
</body>
</html>
```

<Tip>
  Place both script tags just before the closing `</body>` tag. The `defer` attribute on `app.min.js` ensures it loads after the config is set without blocking page rendering.
</Tip>

### Full-Screen Widget

To make the widget fill the entire viewport, use `inline` mode and mount the widget into a full-page `#rapida-chat-app` element:

```html theme={null}
<style>
  html,
  body,
  #rapida-chat-app {
    width: 100%;
    height: 100%;
    margin: 0;
  }
</style>
<div id="rapida-chat-app"></div>
<script>
  window.chatbotConfig = {
    assistant_id: "YOUR_ASSISTANT_ID",
    token: "YOUR_PROJECT_CREDENTIAL_KEY",
    layout: {
      mode: "inline",
      showFrame: false,
    },
    header: {
      isOn: false,
    },
  };
</script>
<script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
```

## Platform Integration Guides

<AccordionGroup>
  <Accordion title="WordPress">
    1. Go to **Appearance** > **Theme File Editor** (or use a plugin like **Insert Headers and Footers**)
    2. Add the following before the closing `</body>` tag in your theme's `footer.php`:

    ```html theme={null}
    <script>
      window.chatbotConfig = {
        assistant_id: "YOUR_ASSISTANT_ID",
        token: "YOUR_PROJECT_CREDENTIAL_KEY",
      };
    </script>
    <script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
    ```

    3. Save and verify the widget loads on your site
  </Accordion>

  <Accordion title="Shopify">
    1. Go to **Online Store** > **Themes** > **Edit Code**
    2. Open `theme.liquid`
    3. Add the scripts before the closing `</body>` tag:

    ```html theme={null}
    <script>
      window.chatbotConfig = {
        assistant_id: "YOUR_ASSISTANT_ID",
        token: "YOUR_PROJECT_CREDENTIAL_KEY",
      };
    </script>
    <script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
    ```

    4. Save and preview your store
  </Accordion>

  <Accordion title="Webflow">
    1. Go to **Project Settings** > **Custom Code**
    2. Paste in the **Footer Code** section:

    ```html theme={null}
    <script>
      window.chatbotConfig = {
        assistant_id: "YOUR_ASSISTANT_ID",
        token: "YOUR_PROJECT_CREDENTIAL_KEY",
      };
    </script>
    <script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
    ```

    3. Publish your site
  </Accordion>

  <Accordion title="Squarespace">
    1. Go to **Settings** > **Advanced** > **Code Injection**
    2. Paste in the **Footer** section:

    ```html theme={null}
    <script>
      window.chatbotConfig = {
        assistant_id: "YOUR_ASSISTANT_ID",
        token: "YOUR_PROJECT_CREDENTIAL_KEY",
      };
    </script>
    <script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
    ```

    3. Save and preview your site
  </Accordion>

  <Accordion title="Next.js">
    Use Next.js `Script` component in your root layout:

    ```tsx theme={null}
    // app/layout.tsx (App Router)
    import Script from "next/script";

    export default function RootLayout({ children }) {
      return (
        <html lang="en">
          <body>
            {children}
            <Script id="rapida-config" strategy="beforeInteractive">
              {`window.chatbotConfig = {
                assistant_id: "${process.env.NEXT_PUBLIC_RAPIDA_ASSISTANT_ID}",
                token: "${process.env.NEXT_PUBLIC_RAPIDA_TOKEN}",
              };`}
            </Script>
            <Script
              src="https://cdn-01.rapida.ai/public/scripts/app.min.js"
              strategy="lazyOnload"
            />
          </body>
        </html>
      );
    }
    ```
  </Accordion>

  <Accordion title="Vue / Nuxt">
    ```ts theme={null}
    // nuxt.config.ts
    export default defineNuxtConfig({
      app: {
        head: {
          script: [
            {
              children: `window.chatbotConfig = {
                assistant_id: "YOUR_ASSISTANT_ID",
                token: "YOUR_PROJECT_CREDENTIAL_KEY",
              };`,
            },
            {
              src: "https://cdn-01.rapida.ai/public/scripts/app.min.js",
              defer: true,
            },
          ],
        },
      },
    });
    ```

    For plain Vue, add the script tags directly to `public/index.html`.
  </Accordion>

  <Accordion title="Angular">
    Add to `src/index.html` before the closing `</body>` tag:

    ```html theme={null}
    <script>
      window.chatbotConfig = {
        assistant_id: "YOUR_ASSISTANT_ID",
        token: "YOUR_PROJECT_CREDENTIAL_KEY",
      };
    </script>
    <script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
    ```
  </Accordion>

  <Accordion title="Static HTML / Any Website">
    Copy and paste the following into any HTML page:

    ```html theme={null}
    <script>
      window.chatbotConfig = {
        assistant_id: "YOUR_ASSISTANT_ID",
        token: "YOUR_PROJECT_CREDENTIAL_KEY",
      };
    </script>
    <script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
    ```
  </Accordion>
</AccordionGroup>

## Self-Hosted Deployment

If you're running Rapida on your own infrastructure, override the `api_base` to point at your assistant API:

```html theme={null}
<script>
  window.chatbotConfig = {
    assistant_id: "YOUR_ASSISTANT_ID",
    token: "YOUR_PROJECT_CREDENTIAL_KEY",
    api_base: "https://your-assistant-api.example.com",
  };
</script>
<script defer src="https://cdn-01.rapida.ai/public/scripts/app.min.js"></script>
```

You can also self-host the widget script itself. Build the `react-widget` SDK and upload the generated `dist/app.min.js` to your own CDN or static file server:

```bash theme={null}
cd sdks/react-widget
npm install
npm run build
# Upload dist/app.min.js to your CDN
```

Then reference your self-hosted script:

```html theme={null}
<script defer src="https://your-cdn.example.com/scripts/app.min.js"></script>
```

## How It Works

When the widget script loads, it:

1. Reads configuration from `window.chatbotConfig`
2. Reuses an existing `<div id="rapida-chat-app">` or creates one and appends it to the page `<body>`
3. Initialises a `VoiceAgent` instance using the `@rapidaai/react` SDK with the web plugin client connection
4. Fetches the assistant's web plugin deployment config (greeting, suggestions, voice settings)
5. Renders the configured layout: floating launcher, docked side panel, or inline chat
6. Supports both text input and voice input (with microphone visualizer, device selection, and mute controls)
7. Passes supported UI configuration through to the native IBM AI Chat layer
8. Auto-detects language changes on the `<html lang="">` attribute
9. Persists the user ID in `localStorage` (`rpd__uuid`) across sessions when no `user.user_id` is provided

## Widget Features

The pre-built widget includes:

* **Text chat** — Type messages and receive markdown-rendered responses
* **Voice input** — Click the audio icon to switch to voice mode with real-time microphone visualization
* **Microphone device selector** — Choose from available input devices via a dropdown flyout
* **Mute/unmute** — Toggle microphone during voice conversations
* **Quickstart suggestions** — Clickable buttons from your deployment's configured suggestions
* **Session reset** — Restart the conversation via the header button
* **Auto-scroll** — Chat automatically scrolls to the latest message
* **Layout modes** — Use floating, docked-right, docked-left, or inline rendering
* **Theme controls** — Use light, dark, system, or explicit UI token injection

## Input and Output Modes

| Voice Input | Voice Output | User Experience                                 |
| ----------- | ------------ | ----------------------------------------------- |
| Disabled    | Disabled     | Text-only chat                                  |
| Enabled     | Disabled     | Users speak, assistant replies with text        |
| Disabled    | Enabled      | Users type, assistant replies with voice + text |
| Enabled     | Enabled      | Full voice conversation with text transcript    |

## Troubleshooting

| Issue                              | Solution                                                                                                                                                                                                    |
| ---------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| Widget does not appear             | Verify `assistant_id` and `token` are correct. Check the browser console for errors — the widget logs `"Please provide an assistant_id"` or `"Please provide an authentication token"` if either is missing |
| Voice input not working            | Ensure the page is served over HTTPS (required for microphone access). Check that the deployment has STT configured                                                                                         |
| Widget loads but shows no greeting | Ensure you have an active **Web Widget** deployment for this assistant (not an SDK/API deployment)                                                                                                          |
| User ID resets across visits       | The widget stores the auto-generated ID in `localStorage` as `rpd__uuid`. If `localStorage` is cleared, a new ID is generated. Pass a stable `user.user_id` in the config to avoid this                     |
| CORS errors in console             | If self-hosting, ensure your reverse proxy allows requests from your website's origin to the assistant API                                                                                                  |
| `window.chatbotConfig` not read    | Make sure the config script runs **before** `app.min.js`. Use a regular `<script>` tag (not `defer`) for the config, and `defer` on the widget script                                                       |

## Use Cases

<CardGroup cols={2}>
  <Card title="Customer Support">
    Provide instant answers and reduce support ticket volume with 24/7 voice-enabled help.
  </Card>

  <Card title="Lead Generation">
    Engage visitors with qualifying questions and route them to your sales team.
  </Card>

  <Card title="Product Recommendations">
    Guide users through product catalogs with personalized suggestions.
  </Card>

  <Card title="Appointment Scheduling">
    Let users book appointments directly through conversational flow.
  </Card>
</CardGroup>

## Related

* [Create an Assistant](/assistants/create-assistant) — Set up your assistant before deploying
* [Listen](/assistants/configuration/listen) — Choose and tune STT, VAD, noise cancellation, and EOS settings
* [Speak](/assistants/configuration/speak) — Choose and tune TTS, voice, pronunciation, and speech delivery settings
* [Web App (React SDK)](/voice-deployment-options/web-app) — Full SDK integration for custom React apps with complete UI control
* [Credentials](/credential/rapida-credentials) — Manage your project credential keys
* [Conversation Logs](/activity/conversation-logs) — Monitor widget conversations
* [Webhooks](/assistants/webhook/overview) — Receive post-conversation events
