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

# Embedding Widget

> Embed a Ringg AI voice or chat assistant on your website.

Use this quickstart to add a Ringg AI web-call widget to a page. Start with the minimal snippet, verify it in staging, then add branding, chat mode, events, and production controls from the linked reference pages.

<CardGroup cols={2}>
  <Card title="Configuration Reference" icon="sliders-horizontal" href="/get-started/guides/embedding-widget-configuration">
    Load options, variables, positioning, trigger styling, and feedback screens.
  </Card>

  <Card title="Lifecycle Events" icon="radio" href="/get-started/guides/embedding-widget-events">
    Browser events the widget emits about its own state: open/close, conversation start/end, feedback.
  </Card>

  <Card title="Agent Actions" icon="mouse-pointer-click" href="/get-started/guides/embedding-widget-agent-actions">
    Custom browser events the agent dispatches on the host page, configured under Interactive Components.
  </Card>

  <Card title="Chat and Widgets" icon="message-square" href="/get-started/guides/embedding-widget-chat-widgets">
    Text mode, chat-only embeds, calendar widgets, form widgets, and prompt examples.
  </Card>

  <Card title="Customization" icon="palette" href="/get-started/guides/embedding-widget-customization">
    Restyle and script the widget through stable data-ringg attributes.
  </Card>

  <Card title="Production QA and Security" icon="shield-check" href="/get-started/guides/embedding-widget-production-qa-security">
    Domain whitelisting, CSP, CDN pinning, browser QA, and launch checks.
  </Card>
</CardGroup>

## Prerequisites

<Check>An active Ringg AI account.</Check>
<Check>An assistant configured for Webcall in the Ringg AI dashboard.</Check>
<Check>The assistant `agentId` and the webcall public key from the generated embed code (used as `authorization: "Bearer <key>"`).</Check>
<Check>Access to add JavaScript to your website HTML or tag manager.</Check>
<Check>Each staging and production domain added to the assistant's Whitelist Domains list.</Check>

<Warning>
  The widget snippet runs in the browser and includes the webcall public key in an `authorization: "Bearer <key>"` header. The key is scoped to a single assistant and its whitelisted domains — use only the embed code generated for a web-call assistant, whitelist the exact domains where it can run, and never expose a broad backend integration key in public pages. Rotate the key from the dashboard if it is ever compromised.
</Warning>

## Quickstart

<Steps>
  <Step title="Configure the assistant for web calls">
    Open the assistant in the Ringg AI dashboard, go to the WebCall settings, and add your website domain to **Whitelist Domains**.

    Add staging domains separately, such as `staging.example.com`, instead of using one broad production-only assumption.
  </Step>

  <Step title="Add the widget snippet">
    Paste this near the end of the page, preferably before the closing `</body>` tag. Pick the bundle that matches your host page.

    <Tabs>
      <Tab title="Modern bundler or module-aware page">
        Use `dv-agent.es.js` when the page is built with Vite, webpack, Next, or any other module-aware setup, or when the snippet runs inside `<script type="module">`.

        ```html theme={null}
        <script type="module">
          function loadAgentsCdn(version, done) {
            const stylesheet = document.createElement("link");
            stylesheet.rel = "stylesheet";
            stylesheet.type = "text/css";
            stylesheet.href = `https://cdn.jsdelivr.net/npm/@desivocal/agents-cdn@${version}/dist/style.css`;

            const script = document.createElement("script");
            script.type = "module";
            script.onload = done;
            script.src = `https://cdn.jsdelivr.net/npm/@desivocal/agents-cdn@${version}/dist/dv-agent.es.js`;

            document.head.appendChild(stylesheet);
            document.head.appendChild(script);
          }

          loadAgentsCdn("latest", function () {
            loadAgent({
              agentId: "your-agent-id",
              authorization: "Bearer your-webcall-public-key",
              variables: {},
              buttons: {},
            });
          });
        </script>
        ```
      </Tab>

      <Tab title="jQuery or legacy page">
        Use `dv-agent.umd.js` when the host page uses jQuery, an older CMS theme, or any plain `<script>` setup without a module bundler.

        ```html theme={null}
        <script>
          function loadAgentsCdn(version, done) {
            const stylesheet = document.createElement("link");
            stylesheet.rel = "stylesheet";
            stylesheet.type = "text/css";
            stylesheet.href = `https://cdn.jsdelivr.net/npm/@desivocal/agents-cdn@${version}/dist/style.css`;

            const script = document.createElement("script");
            script.type = "text/javascript";
            script.onload = done;
            script.src = `https://cdn.jsdelivr.net/npm/@desivocal/agents-cdn@${version}/dist/dv-agent.umd.js`;

            document.head.appendChild(stylesheet);
            document.head.appendChild(script);
          }

          loadAgentsCdn("latest", function () {
            loadAgent({
              agentId: "your-agent-id",
              authorization: "Bearer your-webcall-public-key",
              variables: {},
              buttons: {},
            });
          });
        </script>
        ```
      </Tab>
    </Tabs>

    <Note>
      The ES bundle is only safe inside module-aware setups. Loading `dv-agent.es.js` as a plain `<script>` leaks internals onto `window` and can clobber host page globals like jQuery's `$`. Reach for the UMD build on any non-module page.
    </Note>

    For production, pin a tested CDN version instead of `latest` after validating the widget in staging.
  </Step>

  <Step title="Set the first configuration options">
    Keep the first launch small. Add variables and the default mode first, then layer on styling.

    ```javascript theme={null}
    loadAgent({
      agentId: "your-agent-id",
      authorization: "Bearer your-webcall-public-key",
      variables: {
        callee_name: "John",
        account_id: "ACC-42",
      },
      defaultTab: "audio",
      hideTabSelector: false,
      title: "Talk to our assistant",
      description: "Ask a question or start a voice call.",
    });
    ```
  </Step>

  <Step title="Update Content Security Policy if needed">
    If your site uses CSP, allow the widget CDN for scripts and styles.

    ```text theme={null}
    script-src 'self' https://cdn.jsdelivr.net;
    style-src 'self' https://cdn.jsdelivr.net;
    ```

    If your CSP policy pins exact asset URLs, use the same CDN version in both the loader and the CSP entries.
  </Step>
</Steps>

## Configuration basics

| Option            | Use it for                                                                                                                           |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `agentId`         | The Ringg assistant to load in the widget.                                                                                           |
| `authorization`   | `Bearer <webcall-public-key>`. The webcall public key is generated for the assistant in the dashboard and can be rotated from there. |
| `variables`       | Runtime values passed into the assistant prompt, such as names or account IDs.                                                       |
| `defaultTab`      | `"audio"` for voice first or `"text"` for chat first.                                                                                |
| `hideTabSelector` | Set `true` for voice-only or chat-only experiences.                                                                                  |
| `buttons`         | Trigger button and call button styling or labels.                                                                                    |
| `widgetPosition`  | Fixed floating widget or absolute placement inside a page container.                                                                 |

See the [configuration reference](/get-started/guides/embedding-widget-configuration) for the full option set and examples.

## Test checklist

<Check>The widget script and stylesheet load without console errors.</Check>
<Check>The trigger button appears in the expected location on desktop and mobile.</Check>
<Check>Voice mode asks for microphone permission and can start and end a test call.</Check>
<Check>Chat mode opens if `defaultTab` is set to `"text"`.</Check>
<Check>The domain is whitelisted in the assistant WebCall settings.</Check>
<Check>Your CSP allows the pinned CDN script and stylesheet.</Check>
<Check>Events or analytics listeners fire only once per user action.</Check>

For launch readiness, use the [production QA and security checklist](/get-started/guides/embedding-widget-production-qa-security).

## Rotating the webcall key

You can rotate the webcall public key any time from the assistant's **Widget Configuration** in the dashboard — click **Rotate key** above the generated snippet, then copy the updated snippet and redeploy.
