Add the assistant with one line
Paste a script tag on the client’s website. The chat opens in an isolated iframe, answers only from that client’s own content, and cites its sources.
Quickstart
- Crawl the client website with ingest enabled (backend Swagger, Admin · Crawl, with
auto_ingest: true). Its pages become the assistant’s knowledge base. - Create the site. This prints the snippet with its site token:
cd apps/api
pnpm site create --tenant <tenant id> --name "Client name" \
--domain https://www.client.com --domain https://client.com- Paste the snippet before
</body>on every page:
<script src="https://<widget host>/widget.js" data-site-token="st_…" async></script>That is the whole snippet: colour, side, title and greeting live in the site’s configuration and change without touching the client’s website. Optional attributes override them on one page only:
<script src="https://<widget host>/widget.js" data-site-token="st_…"
data-position="bottom-left" <!-- bottom-right|-left|-center, top-…, left-center, right-center -->
data-offset="24" <!-- px from the screen edge -->
data-width="400" data-height="640" <!-- largest panel size: px, %, vw, vh, rem -->
data-container="#chat" <!-- show the chat inside this element, no launcher -->
data-title="Support" data-subtitle="We reply in seconds"
data-greeting="Hi! How can I help?" data-placeholder="Ask anything…" data-avatar-text="M"
data-accent-color="#F05A2A" data-accent-text-color="#fff"
data-background-color="#fff" data-chat-background-color="#f6f7fb"
data-text-color="#1f2937" data-muted-color="#6b7280" data-border-color="#e5e7eb"
data-radius="rounded" <!-- square | rounded | pill -->
data-font="Inter" <!-- a Google Font name -->
async></script>Colours accept any plain CSS colour; anything else is ignored. Answers are formatted (lists, bold, links) and cite their sources; the visitor can expand the chat to full screen.
Custom attributes
A page can also pass its own key-value pairs to the chatbot, for example the signed-in visitor’s plan. The site declares which names it accepts in the admin panel (Widget → Custom attributes); any other data-* attribute is ignored. An accepted value can be used as {{name}} in the chatbot’s instructions and in the widget’s title, subtitle, greeting and placeholder.
<script src="https://<widget host>/widget.js" data-site-token="st_…"
data-plan="pro" <!-- declared as "plan" in the admin panel -->
data-company="Acme" <!-- declared as "company" -->
async></script>
Instructions: The customer works at {{company}} and is on the {{plan}} plan.
Greeting: Hi! How can we help {{company}} today?Each value is cleaned (no line breaks or braces) and cut to the length set for it, and a name with no value falls back to its default. Values are personalisation only: anyone can edit a page, so never use one to decide what a visitor may see. From React, pass attributes={{ plan: "pro" }} to ChatbotWidget, or attributes to MyraChat.init.
Keys
Every website has a default key, and you can add named keys (Widget → Embed keys), each with its own allowed origins: one for the live site, one for staging. A key can be copied as ready-made embed code, rotated (the old token keeps working for 24 hours) or revoked (the widget disappears from pages that use it).
Configure a site
pnpm site update <site_id> --position left --color "#F05A2A" \
--title "Ask Client" --greeting "Hi! How can I help?"
pnpm site update <site_id> --prompt "You are Client's friendly assistant." --top-k 6
pnpm site update <site_id> --messages-per-day 5000 --tokens-per-day 1000000
pnpm site update <site_id> --disable # assistant off, launcher stays
pnpm site rotate <site_id> --grace-hours 24 # new token; old one stops after 24 h
pnpm site revoke <site_id> # the widget removes itselfChanges apply within seconds on every server. A custom prompt sets the assistant’s persona; the rules that keep answers grounded in the client’s content and cited are always added.
JS API
The script defines window.MyraChat:
MyraChat.open(); // e.g. from your own "Chat with us" button
MyraChat.close();
MyraChat.toggle();
MyraChat.destroy(); // remove the launcher and the chat from the page
// Without data-* attributes: load widget.js, then pass the same options in camelCase.
MyraChat.init({ siteToken: 'st_…', position: 'bottom-left', accentColor: '#F05A2A' });React and Next.js sites can use the package instead of the script tag:
npm install @myra-technolabs/chatbot-widget
import { ChatbotWidget } from '@myra-technolabs/chatbot-widget';
<ChatbotWidget siteToken="st_…" widgetUrl="https://<widget host>" position="bottom-left" />How it stays safe
The widget talks only to the chat API. It never sees the backend, a service key or an admin key, and it never decides which tenant’s content is searched: the server takes that from the site.
Troubleshooting
| No launcher appears | Check the browser console. “not allowed for this site token” means this domain is not in the site’s allowed domains; add it with `pnpm site update <site_id> --domain https://…`. |
| The widget disappeared | The site was revoked or archived, or the token was rotated and its grace period ended (HTTP 410). Use the current snippet. |
| “Too many messages” | A visitor hit the per-minute rate limit. It clears by itself after the time shown. |
| “Not available right now” | The assistant is switched off for the site, or the site used up its daily quota. It resets at 00:00 UTC. |
| Answers say “No relevant info found” | Nothing in the site’s knowledge base matched. Check that the site was crawled and ingested for this tenant. |