documentation
05 integrations

Bot widget

The Exolvra chat widget is a single JavaScript file served from your deployment. It renders a floating chat bubble on your website that talks to a specific bot via the public API. Zero dependencies, Shadow DOM isolated, ~9 KB.

Quick start

  1. Create a bot in the dashboard at /bots/new. Give it a name, description, system prompt, and optionally a knowledge collection.
  2. Generate an API key. Open the bot in edit mode, go to section “05 — API Keys”, click Generate new key. Copy the plaintext exo_... key — it is shown exactly once.
  3. Paste the snippet onto any page of your website:
<script
  src="https://your-exolvra.example/widget/chat-widget.js"
  data-api-key="exo_a1b2c3d4e5f6..."
  data-theme="light"
  data-position="bottom-right"></script>

That’s it. A chat bubble appears in the corner. Clicking it opens a panel that loads the bot’s name, icon, and conversation starters from /api/v1/bots/me and sends messages through /api/v1/chat/completions.

CORS setup

If your site is on a different domain from the Exolvra deployment, add your site’s origin to the key’s Allowed Origins list in the dashboard. The widget will include the browser’s Origin header on every request; the Exolvra API rejects keys whose origin is not on the allowlist.

If you’re embedding the widget on the same Exolvra host that serves the script (the typical “first run” setup), CORS is not required — the browser won’t send an Origin header on same-origin requests.

Script attributes

AttributeRequiredDefaultDescription
data-api-keyyesPlaintext bot API key from the dashboard (exo_...)
data-themenolightlight or dark
data-positionnobottom-rightbottom-right or bottom-left
data-originnoscript src originOverride the API base URL if you host the script on a CDN separate from the Exolvra deployment

What the widget shows

  • Floating bubble — icon in the configured corner
  • Chat panel — 380×580 by default, responsive on mobile
  • Header — bot icon and name (fetched from /api/v1/bots/me)
  • Conversation starters — clickable chips (first four from the bot’s configured starters) shown on a fresh session
  • Message stream — user and assistant bubbles, markdown-style text, scrollable
  • Input box and Send button — submits via the OpenAI-compatible endpoint

Session persistence

The widget stores a per-bot session id in localStorage under the key exolvra-widget-session:<botId>. This is passed as the user field on every chat completion request, which the Exolvra backend uses to thread multi-turn conversations into the same session. Clearing browser storage (or opening an incognito window) starts a fresh conversation.

React / Vue / Next.js integration

The widget is a vanilla <script> tag — any framework can host it. The simplest pattern is a top-level layout component that appends the script on mount.

React

import { useEffect } from "react";

export function ExolvraWidget({ apiKey }: { apiKey: string }) {
  useEffect(() => {
    const script = document.createElement("script");
    script.src = "https://your-exolvra.example/widget/chat-widget.js";
    script.setAttribute("data-api-key", apiKey);
    script.setAttribute("data-theme", "light");
    script.setAttribute("data-position", "bottom-right");
    document.body.appendChild(script);
    return () => {
      script.remove();
      const host = document.getElementById("exolvra-chat-widget");
      if (host) host.remove();
    };
  }, [apiKey]);
  return null;
}

Next.js (App Router)

// app/layout.tsx
import Script from "next/script";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        {children}
        <Script
          src="https://your-exolvra.example/widget/chat-widget.js"
          data-api-key={process.env.NEXT_PUBLIC_EXOLVRA_KEY}
          data-theme="light"
          strategy="lazyOnload"
        />
      </body>
    </html>
  );
}

Theming

The widget ships with two themes (light and dark) selected via data-theme. For deeper brand customisation, fork chat-widget.js on your own deployment — it’s a single file with an inline <style> block you can edit to change colours, border radii, or fonts.

Security model

The widget is the external, public-facing entry point to a bot. The underlying API key has hard restrictions that cannot be lifted from the browser:

  • Cloud mode is always enforced — network and memory tools only, no filesystem, shell, or browser access
  • CLI providers are blocked — bot API sessions cannot be routed through external CLI tools
  • Specialists are unreachable — API keys can only bind to bots, not your internal specialist workforce
  • Key-level CORS — stolen keys still fail if used from an unauthorised origin
  • Per-key revocation — instantly kill a leaked key from the dashboard

Demo page

A minimal example page ships at /widget/demo.html on your deployment. Open it in your browser, edit the file to set a real key, and refresh to try the widget end-to-end.

Troubleshooting

“Could not reach the bot” banner. The key is wrong, revoked, or expired — check the dashboard API keys tab. Or the bound bot was deleted — re-create the key against a live bot. Or CORS rejected the origin — add your site to the key’s allowed origins list.

Widget renders but messages fail. Same causes as above, plus: the backend could be routing through a model the bot doesn’t have credentials for. Check the bot’s configured model in the dashboard.

Bubble doesn’t appear at all. The <script> tag is missing data-api-key — check the browser console for the warning. Or the page has a CSP that blocks script-src from the Exolvra origin — add it to your CSP.