Installation Guides
The hosted widget.js integration is the no-build path when you want ChattyBox to maintain the interface and transport. If your app should initialize the same UI from npm code, use mountWidget(). To own the UI, use the headless SDK.
Before Installing
Complete the Getting Started flow first: configure and scrape the source, review indexed pages, and verify representative answers in Test Chat.
Then create a browser-safe key in Public Keys and restrict its allowed origins. Return to Embed, select that key, finish any hosted-widget customization, and copy the generated snippet. It includes the public key and API URL for your project:
<script
src="https://chattybox.ai/widget.js"
data-api-key="YOUR_API_KEY"
data-api-url="YOUR_WIDGET_API_URL"
async
></script>
For docs-oriented platforms, see the MkDocs AI chatbot, VitePress AI chatbot, and GitBook AI chatbot guides.
Replace YOUR_API_KEY with the public widget key from your dashboard. Keep the data-api-url value exactly as shown in the dashboard. In production, this is a stable https://...convex.site/chat URL for the public widget API.
What Belongs in the Script
Use script attributes for values that must be available before the widget can start:
| Attribute | Required | Use it for |
|---|---|---|
src | Yes | Loading the ChattyBox widget JavaScript. |
data-api-key | Yes | Identifying the public widget key for your project. |
data-api-url | Yes | Sending widget requests to the ChattyBox API. |
data-locale | No | Forcing the widget UI language on a specific page. |
Use dashboard settings for everything that should be managed without redeploying your site:
- Widget colors, position, icon, title, and welcome message.
- Default language mode and whether
data-localeoverrides are allowed. - Public key creation, deletion, and any allowed-origin restrictions configured for your project.
- Scraping, re-scraping, test chat, analytics, and content gaps.
If you enable the config-as-code lock, assistant, source, runtime, and supported widget settings come from the deployed config instead of dashboard forms. Public keys and allowed origins remain project setup credentials, not config-file values.
Plain HTML
Paste the snippet once near the end of body, just before </body>. This works for static HTML, hand-coded sites, and templates that expose a global footer.
<!doctype html>
<html lang="en">
<head>
<title>Example Site</title>
</head>
<body>
<main>
<!-- Page content -->
</main>
<script
src="https://chattybox.ai/widget.js"
data-api-key="YOUR_API_KEY"
data-api-url="YOUR_WIDGET_API_URL"
async
></script>
</body>
</html>
Next.js / React App Shell
For a Next.js App Router site, add the widget to app/layout.tsx with next/script so it loads once for the whole app.
import Script from "next/script";
import type { ReactNode } from "react";
export default function RootLayout({ children }: { children: ReactNode }) {
return (
<html lang="en">
<body>
{children}
<Script
src="https://chattybox.ai/widget.js"
data-api-key="YOUR_API_KEY"
data-api-url="YOUR_WIDGET_API_URL"
strategy="afterInteractive"
/>
</body>
</html>
);
}
For a React single-page app, add the script once in your top-level app shell or HTML template. Do not inject it from every route component.
import { useEffect } from "react";
export function ChattyBoxWidget() {
useEffect(() => {
if (document.getElementById("chattybox-widget-script")) return;
const script = document.createElement("script");
script.id = "chattybox-widget-script";
script.src = "https://chattybox.ai/widget.js";
script.async = true;
script.setAttribute("data-api-key", "YOUR_API_KEY");
script.setAttribute("data-api-url", "YOUR_WIDGET_API_URL");
script.setAttribute("data-chattybox-widget", "true");
document.body.appendChild(script);
}, []);
return null;
}
Docusaurus
For Docusaurus, create or update src/theme/Root.tsx so the widget is available across docs pages.
import React, { useEffect } from "react";
export default function Root({ children }: { children: React.ReactNode }) {
useEffect(() => {
if (document.getElementById("chattybox-widget-script")) return;
const script = document.createElement("script");
script.id = "chattybox-widget-script";
script.src = "https://chattybox.ai/widget.js";
script.async = true;
script.setAttribute("data-api-key", "YOUR_API_KEY");
script.setAttribute("data-api-url", "YOUR_WIDGET_API_URL");
script.setAttribute("data-chattybox-widget", "true");
document.body.appendChild(script);
}, []);
return <>{children}</>;
}
If your Docusaurus site has translated routes, set data-locale from the current page language or rely on the page's <html lang> value.
Keep the loader in your persistent application shell. Do not recreate or remove it during normal client-side route changes.
Custom Interface
The hosted widget is optional. If you want full control over rendering, message state, and interaction design, use the JavaScript SDK with the same public widget API key and widget API URL.
Generic CMS/Custom HTML
Most CMS platforms have a global custom code, footer, or theme template area. Add the script there so every public page can load the widget.
Use this path for Webflow, Framer, Squarespace, Wix custom code areas, Shopify themes, HubSpot templates, and custom CMS platforms that let you edit global HTML.
<script
src="https://chattybox.ai/widget.js"
data-api-key="YOUR_API_KEY"
data-api-url="YOUR_WIDGET_API_URL"
async
></script>
Before publishing, confirm the CMS does not strip data-api-key, data-api-url, or async from custom scripts.
Google Tag Manager
Use Google Tag Manager when your team already manages third-party scripts through GTM.
- Open your GTM container.
- Create a new Custom HTML tag.
- Paste the ChattyBox snippet.
- Use an All Pages trigger, or a narrower trigger for only the pages that should show the widget.
- Preview the container, verify the widget loads, then publish.
<script
src="https://chattybox.ai/widget.js"
data-api-key="YOUR_API_KEY"
data-api-url="YOUR_WIDGET_API_URL"
async
></script>
If your site uses consent mode or a tag consent policy, ensure the widget is allowed to load on the pages where visitors need help.
WordPress
ChattyBox does not require a WordPress plugin. Use one of the script locations your WordPress setup already supports:
- Theme settings that provide header or footer scripts.
- A child theme that controls the footer template.
- A header/footer script plugin.
- Google Tag Manager if your WordPress site already uses it.
Paste the snippet in a global footer location so it appears on published pages, posts, docs, and knowledge base articles where the chatbot should be available.
<script
src="https://chattybox.ai/widget.js"
data-api-key="YOUR_API_KEY"
data-api-url="YOUR_WIDGET_API_URL"
async
></script>
Avoid adding the widget to wp-admin, checkout, account, or private membership pages unless those pages are intentionally public and supported.
Verification
After installing, run the launch checklist before announcing the chatbot:
- Open a public page in an incognito window.
- Confirm the widget launcher appears.
- Open the widget and ask a real customer question.
- Verify the answer includes source citations.
- Check the browser console for missing
data-api-key, missingdata-api-url, or key/origin errors.