Skip to content

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";functionApp(){return(<DocsChatbotsearch={{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><htmllang="en"><head><metacharset="UTF-8" /><metaname="viewport" content="width=device-width, initial-scale=1.0" /></head><body><scriptsrc="https://unpkg.com/@sqliteai/docs-chatbot/dist/umd/docs-chatbot.min.js"></script><docs-chatbotsearch-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.

<DocsChatbotsearch={{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-chatbotsearch-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.

<DocsChatbotsearch={{url: "your-edge-function-url",apiKey: "your-api-key"}}title="Memory Assistant"variant="embedded"className="h-full"header={{label: "Memory Assistant",showClearButton: true,}}persistence={{key: `memory:${projectId}:${databaseName}`,storage: "session",}}/>
<docs-chatbotsearch-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.

<DocsChatbotsearch={{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.

<DocsChatbotsearch={{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/editorconsole.log("Selected result",result);},}}/>
<docs-chatbotsearch-url="https://yourproject.sqlite.cloud/v2/functions/aisearch-docs"
api-key="your-api-key"
title="Help Center"
></docs-chatbot><script>constchatbot=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.

<DocsChatbotsearch={{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";functionApp(){const[open,setOpen]=useState(false);return(<>{/* Your custom button anywhere in your app */}<buttononClick={()=>setOpen(true)}>Help &Support</button>{/* Chatbot with custom trigger mode */}<DocsChatbotsearch={{url: "your-edge-function-url",apiKey: "your-api-key"}}title="Help Center"dialog={{trigger: "custom", open,onOpenChange: setOpen}}/></>);}

Vanilla JavaScript:

<scriptsrc="https://unpkg.com/@sqliteai/docs-chatbot/dist/umd/docs-chatbot.min.js"></script><!-- Your custom button --><buttonid="help-btn">Help & Support</button><!-- Chatbot with custom trigger mode --><docs-chatbotsearch-url="your-edge-function-url"
api-key="your-api-key"
title="Help Center"
trigger="custom"
></docs-chatbot><script>constchatbot=document.querySelector("docs-chatbot");constbutton=document.getElementById("help-btn");// Open chatbot when button is clickedbutton.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

PropertyTypeRequiredDescription
search{ url: string; apiKey: string }YesSearch transport configuration
search.urlstringYesFull URL of your deployed SQLite Cloud edge function (e.g., https://yourproject.sqlite.cloud/v2/functions/aisearch-docs)
search.apiKeystringYesSQLite Cloud API key with permissions to execute the edge function
titlestringYesTitle displayed in the chatbot header
variant"dialog" | "embedded"NoRendering mode: "dialog" keeps the popup widget behavior, "embedded" renders the chatbot inline (default: "dialog")
emptyState{ title: string; description: string }NoCustomizes the initial empty state of the chatbot
emptyState.titlestringNoMain heading shown before the first message
emptyState.descriptionstringNoSubtext shown below the empty state title
persistence{ key: string; storage?: "session" | "local" }NoPersists messages and composer input under the provided key
persistence.keystringNoStorage key used for persisted conversation state
persistence.storage"session" | "local"NoStorage backend for persistence (default: "session")
header{ showClearButton?: boolean; icon?: ReactNode; label?: ReactNode; closeButton?: ReactNode; closeButtonIcon?: ReactNode; onClose?: () => void }NoHeader-specific controls
header.showClearButtonbooleanNoShows the Clear action in the header when there is conversation history (default: false)
header.iconReactNodeNoVisible header icon. Defaults to the chat icon
header.labelReactNodeNoVisible header label. Defaults to title
header.closeButtonReactNodeNoFull custom close control. If you pass a React element, its onClick is merged with the chatbot close action
header.closeButtonIconReactNodeNoIcon rendered in the close button when the chatbot can be closed. Defaults to X
header.onClose() => voidNoCustom close action for the header. When provided, the close button is shown even in embedded mode
results{ onSelect?: (result: DocumentSearchResult) => void; snippetMaxLines?: number; snippetMaxChars?: number }NoResult-card behavior and display settings
results.onSelect(result: DocumentSearchResult) => voidNoCalled when a result card is selected. When provided, default link navigation is suppressed
results.snippetMaxLinesnumberNoVisually clamps result snippets to the given number of lines
results.snippetMaxCharsnumberNoTruncates result snippets to the given number of characters before rendering
dialog{ trigger?: "default" } | { trigger: "custom"; open: boolean; onOpenChange: (open: boolean) => void }NoDialog-specific configuration
dialog.trigger"default" | "custom"NoTrigger mode for dialog rendering. "default" uses the floating button, "custom" makes open state controlled
dialog.openbooleanYes when dialog.trigger="custom"Controls the chatbot open state in custom-trigger mode
dialog.onOpenChange(open: boolean) => voidYes when dialog.trigger="custom"Callback fired when the open state changes in custom-trigger mode
classNamestringNoExtra classes applied to the root chatbot panel
styleCSSPropertiesNoInline styles applied to the root chatbot panel

Web Component

Attributes

AttributeRequiredDescription
search-urlYesFull URL of your deployed SQLite Cloud edge function (e.g., https://yourproject.sqlite.cloud/v2/functions/aisearch-docs)
api-keyYesSQLite Cloud API key with permissions to execute the edge function
titleYesTitle displayed in the chatbot header
empty-state-titleNoMain heading shown before the first message
empty-state-descriptionNoSubtext shown below the empty state title
persistence-keyNoStorage key used to persist messages and composer input
persistence-storageNoStorage backend for persistence: "session" or "local" (default: "session")
result-snippet-max-linesNoVisually clamps result snippets to the given number of lines
result-snippet-max-charsNoTruncates result snippets to the given number of characters
show-clear-buttonNoWhen present, shows the Clear action in the header
variantNoRendering mode: "dialog" for the popup widget or "embedded" for an inline panel
triggerNoTrigger mode: "default" uses floating button, "custom" requires controlling open property (default: "default")

Properties

PropertyTypeDescription
openbooleanGet or set the chatbot open state (property-only, no attribute)

Events

EventDetailDescription
openchange{ open: boolean }Fired when the chatbot open state changes
resultselectDocumentSearchResultFired when a result card is selected. Call preventDefault() to suppress default link navigation

Theming

Customize the chatbot's appearance using CSS variables.

CSS Variables

VariableDescription
--docs-chatbot-radiusBorder radius
--docs-chatbot-backgroundBackground color
--docs-chatbot-foregroundText color
--docs-chatbot-primaryPrimary color
--docs-chatbot-primary-foregroundPrimary text color
--docs-chatbot-secondarySecondary color
--docs-chatbot-secondary-foregroundSecondary text color
--docs-chatbot-mutedMuted color
--docs-chatbot-muted-foregroundMuted text color
--docs-chatbot-accentAccent color
--docs-chatbot-accent-foregroundAccent text color
--docs-chatbot-borderBorder color
--docs-chatbot-inputInput background color
--docs-chatbot-ringFocus ring color
--docs-chatbot-cardCard background color
--docs-chatbot-card-foregroundCard text color
--docs-chatbot-popoverPopover background color
--docs-chatbot-popover-foregroundPopover text color
--docs-chatbot-destructiveDestructive/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.60.20);
--docs-chatbot-primary-foreground:oklch(100);
--docs-chatbot-border:oklch(0.8500);
--docs-chatbot-radius:8px;
}
import{DocsChatbot}from"@sqliteai/docs-chatbot";import"./styles.css";// Your CSS file with overridesfunctionApp(){return(<DocsChatbotsearch={{url: "your-edge-function-url",apiKey: "your-api-key"}}title="Help Center"/>);}

Vanilla JavaScript:

<style>docs-chatbot {
--docs-chatbot-primary:oklch(0.60.20);
--docs-chatbot-primary-foreground:oklch(100);
--docs-chatbot-border:oklch(0.8500);
--docs-chatbot-radius:8px;
}
</style><docs-chatbotsearch-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

Stars

1 star

Watchers

1 watching

Forks

Contributors

Languages