Skip to content

sqliteai/docs-chatbot

Repository files navigation

@sqliteai/docs-chatbot

Status

Embeddable AI chatbot for documentation, powered by SQLite Cloud.

Local Testing

For local testing, the package includes a built-in mock endpoint: mock://docs-chatbot.

The repo demos and examples now prefer that mock endpoint by default, even if VITE_SEARCH_API_URL exists.

Quick Start

Prerequisites

Before using this chatbot, you need to:

  1. Index your documentation - Use the SQLite AI Search Action to create embeddings from your documentation files
  2. Create an edge function - Follow the setup guide to deploy the search edge function

React

npm install @sqliteai/docs-chatbot
import { DocsChatbot } from "@sqliteai/docs-chatbot";
import "@sqliteai/docs-chatbot/style.css";

function App() {
  return (
    <DocsChatbot
      search={{
        url: "https://yourproject.sqlite.cloud/v2/functions/aisearch-docs",
        apiKey: "your-api-key",
      }}
      title="Help Center"
      variant="embedded"
    />
  );
}

For local-only testing, replace search.url with mock://docs-chatbot and use any placeholder API key such as demo-key.

If you want the demos to use a real backend instead, set VITE_USE_REAL_SEARCH=true.

Vanilla JavaScript

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  </head>
  <body>
    <script src="https://unpkg.com/@sqliteai/docs-chatbot/dist/umd/docs-chatbot.min.js"></script>

    <docs-chatbot
      search-url="https://yourproject.sqlite.cloud/v2/functions/aisearch-docs"
      api-key="your-api-key"
      title="Help Center"
    >
    </docs-chatbot>
  </body>
</html>

Display Modes

Embedded Panel

Render the chatbot inline inside your layout. This is the mode to use when you want the chat UI to live inside an existing panel, sidebar, or page section.

<DocsChatbot
  search={{ url: "your-edge-function-url", apiKey: "your-api-key" }}
  title="Help Center"
  variant="embedded"
  className="max-w-2xl h-[600px]"
  persistence={{ key: "help-center" }}
  results={{ snippetMaxLines: 5 }}
/>
<docs-chatbot
  search-url="https://yourproject.sqlite.cloud/v2/functions/aisearch-docs"
  api-key="your-api-key"
  title="Help Center"
  variant="embedded"
></docs-chatbot>

In embedded mode, the host layout should provide height. The component no longer renders its own outer frame.

Conversation Persistence

To preserve chat history across unmounts or context switches, pass a persistence key. In dashboard-style layouts, use a different key per database or per workspace.

<DocsChatbot
  search={{ url: "your-edge-function-url", apiKey: "your-api-key" }}
  title="Memory Assistant"
  variant="embedded"
  className="h-full"
  persistence={{
    key: `memory:${projectId}:${databaseName}`,
    storage: "session",
  }}
/>
<docs-chatbot
  search-url="https://yourproject.sqlite.cloud/v2/functions/aisearch-docs"
  api-key="your-api-key"
  title="Help Center"
  persistence-key="help-center"
  persistence-storage="session"
></docs-chatbot>

The floating dialog modes also keep running when you click outside the widget. They no longer dismiss on background clicks.

Snippet Display

To keep result cards compact, you can clamp snippet height visually and/or truncate by characters.

<DocsChatbot
  search={{ url: "your-edge-function-url", apiKey: "your-api-key" }}
  title="Memory Assistant"
  variant="embedded"
  results={{
    snippetMaxLines: 5,
    snippetMaxChars: 320,
  }}
/>

Result Selection

To intercept result clicks and route them into your own UI, use results.onSelect in React or listen for the resultselect event on the web component.

<DocsChatbot
  search={{ url: "your-edge-function-url", apiKey: "your-api-key" }}
  title="Memory Assistant"
  variant="embedded"
  results={{
    onSelect: (result) => {
      // Example: select the matching file in your tree/editor
      console.log("Selected result", result);
    },
  }}
/>
<docs-chatbot
  search-url="https://yourproject.sqlite.cloud/v2/functions/aisearch-docs"
  api-key="your-api-key"
  title="Help Center"
></docs-chatbot>

<script>
  const chatbot = document.querySelector("docs-chatbot");

  chatbot.addEventListener("resultselect", (event) => {
    event.preventDefault();
    console.log("Selected result", event.detail);
  });
</script>

Trigger Modes

Default Trigger

Screen Shot 2025-10-24 at 14 39 33 PM

Adds a floating button in the bottom-right corner that opens the chatbot when clicked.

<DocsChatbot
  search={{ url: "your-edge-function-url", apiKey: "your-api-key" }}
  title="Help Center"
  variant="dialog"
/>

Custom Trigger

Screen Shot 2025-10-24 at 14 42 16 PM

Use your own button or trigger element to control when the chatbot opens. This mode is useful when you want the chatbot to integrate seamlessly with your existing UI design or place the trigger in a specific location (like a navigation bar or help menu).

React:

import { DocsChatbot } from "@sqliteai/docs-chatbot";
import "@sqliteai/docs-chatbot/style.css";
import { useState } from "react";

function App() {
  const [open, setOpen] = useState(false);

  return (
    <>
      {/* Your custom button anywhere in your app */}
      <button onClick={() => setOpen(true)}>Help & Support</button>

      {/* Chatbot with custom trigger mode */}
      <DocsChatbot
        search={{ url: "your-edge-function-url", apiKey: "your-api-key" }}
        title="Help Center"
        dialog={{ trigger: "custom", open, onOpenChange: setOpen }}
      />
    </>
  );
}

Vanilla JavaScript:

<script src="https://unpkg.com/@sqliteai/docs-chatbot/dist/umd/docs-chatbot.min.js"></script>

<!-- Your custom button -->
<button id="help-btn">Help & Support</button>

<!-- Chatbot with custom trigger mode -->
<docs-chatbot
  search-url="your-edge-function-url"
  api-key="your-api-key"
  title="Help Center"
  trigger="custom"
>
</docs-chatbot>

<script>
  const chatbot = document.querySelector("docs-chatbot");
  const button = document.getElementById("help-btn");

  // Open chatbot when button is clicked
  button.addEventListener("click", () => {
    chatbot.open = true;
  });

  // Listen to state changes (optional)
  chatbot.addEventListener("openchange", (e) => {
    console.log("Chatbot open:", e.detail.open);
  });
</script>

API Reference

React Component Props

Property Type Required Description
search { url: string; apiKey: string } Yes Search transport configuration
search.url string Yes Full URL of your deployed SQLite Cloud edge function (e.g., https://yourproject.sqlite.cloud/v2/functions/aisearch-docs)
search.apiKey string Yes SQLite Cloud API key with permissions to execute the edge function
title string Yes Title displayed in the chatbot header
variant "dialog" | "embedded" No Rendering mode: "dialog" keeps the popup widget behavior, "embedded" renders the chatbot inline (default: "dialog")
emptyState { title: string; description: string } No Customizes the initial empty state of the chatbot
emptyState.title string No Main heading shown before the first message
emptyState.description string No Subtext shown below the empty state title
persistence { key: string; storage?: "session" | "local" } No Persists messages and composer input under the provided key
persistence.key string No Storage key used for persisted conversation state
persistence.storage "session" | "local" No Storage backend for persistence (default: "session")
header { showClearButton?: boolean } No Header-specific controls
header.showClearButton boolean No Shows the Clear action in the header when there is conversation history (default: false)
results { onSelect?: (result: DocumentSearchResult) => void; snippetMaxLines?: number; snippetMaxChars?: number } No Result-card behavior and display settings
results.onSelect (result: DocumentSearchResult) => void No Called when a result card is selected. When provided, default link navigation is suppressed
results.snippetMaxLines number No Visually clamps result snippets to the given number of lines
results.snippetMaxChars number No Truncates result snippets to the given number of characters before rendering
dialog { trigger?: "default" } | { trigger: "custom"; open: boolean; onOpenChange: (open: boolean) => void } No Dialog-specific configuration
dialog.trigger "default" | "custom" No Trigger mode for dialog rendering. "default" uses the floating button, "custom" makes open state controlled
dialog.open boolean Yes when dialog.trigger="custom" Controls the chatbot open state in custom-trigger mode
dialog.onOpenChange (open: boolean) => void Yes when dialog.trigger="custom" Callback fired when the open state changes in custom-trigger mode
className string No Extra classes applied to the root chatbot panel
style CSSProperties No Inline styles applied to the root chatbot panel

Web Component

Attributes

Attribute Required Description
search-url Yes Full URL of your deployed SQLite Cloud edge function (e.g., https://yourproject.sqlite.cloud/v2/functions/aisearch-docs)
api-key Yes SQLite Cloud API key with permissions to execute the edge function
title Yes Title displayed in the chatbot header
empty-state-title No Main heading shown before the first message
empty-state-description No Subtext shown below the empty state title
persistence-key No Storage key used to persist messages and composer input
persistence-storage No Storage backend for persistence: "session" or "local" (default: "session")
result-snippet-max-lines No Visually clamps result snippets to the given number of lines
result-snippet-max-chars No Truncates result snippets to the given number of characters
show-clear-button No When present, shows the Clear action in the header
variant No Rendering mode: "dialog" for the popup widget or "embedded" for an inline panel
trigger No Trigger mode: "default" uses floating button, "custom" requires controlling open property (default: "default")

Properties

Property Type Description
open boolean Get or set the chatbot open state (property-only, no attribute)

Events

Event Detail Description
openchange { open: boolean } Fired when the chatbot open state changes
resultselect DocumentSearchResult Fired when a result card is selected. Call preventDefault() to suppress default link navigation

Theming

Customize the chatbot's appearance using CSS variables.

CSS Variables

Variable Description
--docs-chatbot-radius Border radius
--docs-chatbot-background Background color
--docs-chatbot-foreground Text color
--docs-chatbot-primary Primary color
--docs-chatbot-primary-foreground Primary text color
--docs-chatbot-secondary Secondary color
--docs-chatbot-secondary-foreground Secondary text color
--docs-chatbot-muted Muted color
--docs-chatbot-muted-foreground Muted text color
--docs-chatbot-accent Accent color
--docs-chatbot-accent-foreground Accent text color
--docs-chatbot-border Border color
--docs-chatbot-input Input background color
--docs-chatbot-ring Focus ring color
--docs-chatbot-card Card background color
--docs-chatbot-card-foreground Card text color
--docs-chatbot-popover Popover background color
--docs-chatbot-popover-foreground Popover text color
--docs-chatbot-destructive Destructive/error color

Examples

React:

/* In your main CSS file, import the chatbot styles first */
@import "@sqliteai/docs-chatbot/style.css";

/* Then override the variables */
:root {
  --docs-chatbot-primary: oklch(0.6 0.2 0);
  --docs-chatbot-primary-foreground: oklch(1 0 0);
  --docs-chatbot-border: oklch(0.85 0 0);
  --docs-chatbot-radius: 8px;
}
import { DocsChatbot } from "@sqliteai/docs-chatbot";
import "./styles.css"; // Your CSS file with overrides

function App() {
  return (
    <DocsChatbot
      search={{ url: "your-edge-function-url", apiKey: "your-api-key" }}
      title="Help Center"
    />
  );
}

Vanilla JavaScript:

<style>
  docs-chatbot {
    --docs-chatbot-primary: oklch(0.6 0.2 0);
    --docs-chatbot-primary-foreground: oklch(1 0 0);
    --docs-chatbot-border: oklch(0.85 0 0);
    --docs-chatbot-radius: 8px;
  }
</style>

<docs-chatbot
  search-url="your-edge-function-url"
  api-key="your-api-key"
  title="Help Center"
>
</docs-chatbot>

About

Embeddable AI chatbot for documentation, powered by SQLite Cloud.

Resources

License

Stars

Watchers

Forks

Contributors