
A chat widget is the fastest way to put an AI assistant in front of visitors: no app to build, no login, and the assistant answers from the same knowledge base you use everywhere else. The install is one script tag. The decisions around it are what make the difference between a widget that answers support tickets and one that embarrasses you on the pricing page.
This guide walks through the install, the settings worth deciding before you go live, and the small JavaScript API that lets your page drive the widget.
The install
In the admin panel, open the assistant, go to Channels → Web Widget, add your website's origin, and copy the snippet. It already contains your assistant ID:
<script
src="https://cdn.assistantcore.com/embed/embed.js"
data-assistant-id="YOUR_ASSISTANT_ID"
data-api-base="https://api.assistantcore.com"
async
></script>
Put it once near the end of <body>, or in your framework's root layout so client-side navigation does not load it twice. In Next.js that is a <Script strategy="lazyOnload"> in the root layout. The widget renders inside a Shadow DOM, so your site's CSS and the widget's CSS leave each other alone, and it switches to a full-screen layout on phones.
Three things trip people up on day one:
- Origins must be exact and HTTPS.
https://example.comandhttps://www.example.comare different origins; add production, staging, and preview separately.http://localhostis not accepted; test on an HTTPS preview URL. - One origin, one assistant. The service picks the assistant from the page's origin, so an origin can be allowed on only one assistant.
- Content Security Policy. If your site sets a CSP, allow
https://cdn.assistantcore.cominscript-srcandhttps://api.assistantcore.cominconnect-src.
The widget needs Widget Embed on the assistant owner's plan (Pro and above).
Decide what the widget may do
Anyone who can open your site can chat, and every reply is paid from the assistant owner's credits. Before you publish, make four decisions:
What it answers. The prompt should say what the assistant is for, what it must not promise, and how to redirect off-topic questions. Pair it with a knowledge base that mirrors real questions: pricing, delivery, returns, opening hours, and the FAQ your team answers by hand.
Which tools it can use. Each tool can be limited to specific channels. Keep tools that change data, such as creating orders, off the widget, and leave the read-only ones on. Tools that delete are never offered on the widget, because there is no signed-in person to approve them.
Whether visitors can upload files. Visitor attachments are off by default. Turned on, visitors can send images, PDFs, Office documents, and text files, up to five per message, with per-visitor and per-network hourly limits, and files are deleted after 30 days. Audio and video are not accepted.
What it looks like and says. Light, dark, or match-device theme; bottom-left or bottom-right; a greeting bubble that shows once per visit after a few seconds (never on phones); up to four conversation starters; the message box placeholder; and a privacy policy link in the footer. Name, avatar, and brand color come from the assistant's settings.
Drive the widget from your page
Once loaded, the widget exposes a small API on window.AssistantEmbed. The pattern most sites want is a "Chat with us" button in their own design and no floating launcher:
<script
src="https://cdn.assistantcore.com/embed/embed.js"
data-assistant-id="YOUR_ASSISTANT_ID"
data-api-base="https://api.assistantcore.com"
data-hide-launcher
async
></script>
<button onclick="AssistantEmbed.open()">Chat with us</button>
Pre-filling a message from the page the visitor is on turns a generic chat into a contextual one:
AssistantEmbed.open({ message: "I have a question about order #123" })
The visitor still presses send. For analytics, listen for events:
AssistantEmbed.on("open", () => track("chat_opened"))
AssistantEmbed.on("message", ({ text }) => track("chat_message"))
AssistantEmbed.on("reply", ({ text }) => track("chat_reply"))
If your code runs before the widget has loaded its configuration, queue the calls; they run in order once the widget fires assistantembed:ready:
<script>
window.AssistantEmbed = window.AssistantEmbed || []
AssistantEmbed.push(["open", { message: "Hi!" }])
</script>
Other attributes: data-lang forces en or vi (otherwise the page's <html lang>, then the browser language, then English), and data-offset-x / data-offset-y move the launcher to clear a cookie banner or another floating button. AssistantEmbed.hideLauncher() is useful on checkout pages.
What visitors get
Replies stream in with Markdown rendered, and answers from the knowledge base cite their sources under the reply. The last conversation is restored when a visitor returns in the same browser. Visitors can rate a reply helpful or not, and say what went wrong; those ratings feed the positive-feedback number on your dashboard. When a tool returns a result card, the widget draws the full card with its image and buttons.
Every widget conversation appears in the admin panel under the Widget channel, so your team can read what visitors asked and fix the knowledge base where answers were weak.
Privacy
The widget stores a random visitor ID, the last conversation, and whether the greeting was shown in the visitor's browser, and sends messages and attachments to your assistant. Cover that in your privacy notice, add the notice's address as the widget's privacy link, and check consent requirements in the markets you serve. In Vietnam, the Personal Data Protection Law (Law 91/2025/QH15) has applied since January 1, 2026: what visitors type into the widget is data your business collects, so your notice should say what you use it for.
After the website
The same assistant that answers on your site can answer on Zalo OA, Messenger, WhatsApp, and Telegram, and the Developer API gives you the same streaming chat inside your own interface when the widget is not enough. The complete reference for every setting is in the Web Widget documentation.