Set it up
Open Integrations → Website widget in the console. The guide there, Add Ask AI to your website, takes three steps: your website’s address, one line to paste, and a check that the line is there. An Owner, Administrator or Editor can run it.1
Enter your website's address
Type the address people use to visit your site, such as
https://www.example.com, and select Set up my website. The console then does three things and reports each as it finishes:- Read your website. It connects the address as a website source, reading up to 250 pages of that site and not its subdomains, so the assistant can answer from them. Reading carries on in the background. If you already have sources, this is a tick box, Also read this website as a knowledge source, and you can leave it off.
- Prepare the assistant. It uses an active assistant of yours that can already answer. If none can, it attaches your knowledge to the active assistant you have, or creates one named Website assistant.
- Create the widget. It creates an embed for that assistant, allowed on exactly the address you typed.
2
Copy one line
The guide shows the line to paste. Select Copy, or Email to my developer to open a message in your mail program with the line and a link to these instructions; you choose who receives it.Paste the line, unchanged, before the closing There is no second script to add and nothing to edit. Install it on your platform says where the line goes in WordPress, Shopify, Webflow, Wix, Google Tag Manager, React, Next.js and Docusaurus.The line can be copied again at any time from the embed’s row, so losing it never orphans an embed.
</body> tag on every page that should show the widget, or once into the template every page shares. It is one script tag:3
Check my website
Enter the address of any page that has the line on it and select Check. MITHUNAI reads that page and tells you what it found. What the check reports explains each result.Then open your page, select the Ask AI button at the bottom right and ask a question your content covers.
While your website is still being read, the Ask AI button already appears on your site, and
the assistant answers from your pages once reading finishes. Until then it may reply that it does
not know. Follow the progress under Sources.
Content-Security-Policy and the scripts your site already runs.
What the check reports
The names in brackets are the values Check a widget installation returns.
What the check cannot see
The check reads one page the way a search engine’s crawler would, and that has limits worth knowing before you act on a result.- It reads the page’s HTML only and runs no script. A line added by a tag manager, a consent tool or JavaScript is not in that HTML, so a working widget can read as not found. Open your site and look for the Ask AI button.
- It does not follow redirects. An address that redirects to one ending in a slash, for example from
/docsto/docs/, reads as could not be read. One that redirects to another host, for example fromexample.comtowww.example.com, is checked against the embed’s allowed websites first, so it reads as not allowed unless the address you typed is itself allowed. Enter the final address, the one in the browser’s address bar once the page has loaded. - The page must be public. A page on your own computer, behind a sign-in or on a private network cannot be read.
- It describes the page, not the embed. A page that still carries the line of a revoked embed reads as installed.
- It reads the first megabyte of the page, which is enough for any ordinary page.
Create an embed by hand
To choose the assistant yourself, list several origins or script the setup, create the embed directly.- Console
- API
- Open Integrations → Website widget and select New embed.
- Enter a Name, choose the Assistant that should answer, and list your site under Allowed origins, one per line. Only an active assistant can be chosen.
- Select Create embed. The embed appears in the list with its line to paste, which contains its widget key (
mithunai_wk_…), and its own Check.
https://docs.example.com. See Allowed origins.
Snippets pasted earlier
Snippets pasted earlier, which set the same values on awindow.mithunaiWidget object in a script of their own before the tag, keep working unchanged; that is now the object form.
Configuration options
Each option is adata- attribute on the script tag. Only the first two are required, and the snippet you copy already carries them.
An on-or-off attribute takes exactly
true or false, in lower case: write data-shortcut="true", not data-shortcut on its own. An attribute the widget does not know is ignored, so a snippet written for a newer widget still loads on an older one. A known attribute with a value it cannot accept is refused: the widget logs what is wrong and renders nothing.
Ways it can appear
One embed can appear four ways. The choice is in the line you paste, so the same embed can be a chat bubble on one page and a search box on another. In the console, How it appears beside the line writes it for you.- Chat bubble (
chat, the default). A button in the corner opens a panel with the conversation. - Docked sidebar (
sidebar). The same button opens the panel docked to the full height of the left or right edge (data-position). - Search box (
search). A search box inside the elementdata-targetnames. Each search is answered on its own, with citations and the list of sources it used, and does not carry on from the one before. - Form deflector (
deflector). See below.
Setting the default for an embed (Beta)
An embed can also store how it appears when the page’s snippet has nodata-mode. In the console, open Widget embeds, find the embed and use Presentation (Beta): Let the page decide (the default), Chat bubble or Docked sidebar. The widget reads the stored value when it loads, so changing it reaches every page already carrying the snippet, within the 30 minutes a tab keeps its last answer.
- A snippet that sets
data-modealways wins. The stored value applies only to a page whose snippet names no mode. - Only the chat bubble and the docked sidebar can be stored. The search box and the deflector need
data-target(and, for the deflector,data-formanddata-fields), which only the page can name, so they are set in the snippet. A value of either that was stored through the API is shown in the console and is not applied. - Off by default. Your deployment’s operator turns on stored presentations. While they are off the console’s save is refused with the platform’s message, nothing is stored, and the snippet decides, as before. Access on request.
presentation on Create a widget embed and Update a widget embed; null clears it.
The search box and the deflector need their elements to exist when the page loads. If one is missing, or a selector is not valid, the widget logs which one in the browser console and shows nothing.
Form deflector
The deflector sits beside your support form. As a customer types into the fieldsdata-fields names (typically the subject and the description), it waits until they pause and there is enough to go on, then shows a cited answer inside data-target. It never stops the form being sent.
window.mithunaiWidget object instead, which is also how your own page opens the widget and asks it questions. See Widget customisation.
Colours, logo and product name come from your organisation’s branding, so one snippet stays correct when you rebrand.
The widget renders inside a shadow root, so your site’s styles do not change it and its styles do not leak onto your page. It is a non-modal panel: it moves focus in when opened, returns focus to the launcher when closed (or, when you hide the launcher, to whatever had focus before), closes on Escape, and never traps keyboard focus or locks page scrolling.
Install it on your platform
The widget needs one thing on every page: its script tag. Loading it twice shows one widget, never two. Adddefer or leave it out; do not add type="module", which stops the widget reading its own tag.
- Plain HTML
- WordPress
- Shopify
- Webflow
- Wix
- Google Tag Manager
- React and Next.js
- Docusaurus
Paste the line before the closing
</body> tag of every page, or once into the template every page shares.Which platforms are verified
The steps above follow each platform’s own documentation for adding a script. This table says which of them MITHUNAI has run itself.
If the button does not appear on a platform marked not verified, check the page’s HTML source for the script tag and its two
data- attributes. If the platform has removed them, use the object form, which does not depend on them.
Content-Security-Policy
If your site sends aContent-Security-Policy, the widget needs these four directives. Replace https://app.mithunai.com with the origin your snippet names.
The one-line snippet has no inline script, so
script-src needs nothing more. The object form and the Google Tag Manager form do have one, which script-src must also allow: with 'unsafe-inline', with a nonce or a hash. The widget loads no fonts, frames or media, and needs no font-src, frame-src or media-src entry.
Allowed origins
The embed must list the exact origin of every site that shows the widget. An origin is a scheme, host and optional port, such ashttps://docs.example.com.
- Exact match only. There is no wildcard.
https://example.comdoes not matchhttps://www.example.com; list each one. - No trailing slash or path.
https://docs.example.com/is invalid. - Empty means nowhere. An embed with no allowed origins works on no site.
Origin it likes, which is why the widget key grants so little on its own.
A deployment can also keep a list of its own, in which case a website must be on both. If your origin is listed on the embed exactly and the widget is still refused there, ask whoever operates your MITHUNAI deployment to allow it.
Update the list at any time from Integrations → Website widget or with Update a widget deployment. Sending a new list replaces the old one.
The widget key is public by design
The widget key sits in your page’s HTML where anyone can read it. That is expected: it is not a password and carries almost no authority. Holding it lets someone:- start a conversation with the one assistant the embed names,
- ask questions in a conversation they started,
- read back their own conversation, and rate the answers in it.
Never put an API key (
mithunai_sk_…) in a web page. API keys are secrets. The widget refuses
one, but the value is still published in your page source. If this has happened, revoke the
key immediately.Visitor conversations
Each conversation belongs to the browser tab that started it:
The conversation is read back only when the visitor opens the widget, so a visitor who never opens it costs nothing against your request budget.
Conversations deliberately do not survive a closed tab. Public pages are often read on shared computers, and remembering a conversation would show the next person what the previous visitor typed.
Feedback and copying
Under each finished answer a visitor can copy it, with its numbered sources, and rate it with a thumbs up or thumbs down. A reply in which the assistant declined can be rated but not copied. A thumbs down offers an optional note of up to 1,000 characters. Selecting the other thumb changes the rating, and selecting the same thumb again withdraws it. An answer rated unhelpful appears under Coverage gaps in the console as rated unhelpful, with the visitor’s note, alongside the questions the assistant could not answer. A visitor can rate only answers in their own conversation. A rating is stored but not shown again after a reload: the thumbs under an answer that was read back start unset, because reading each rating back would spend the embed’s request budget. Selecting a thumb then sets or replaces the stored rating. A custom interface can do the same with Rate a widget answer, Get a widget answer’s rating and Withdraw a widget answer’s rating.Revoke an embed
Revoke an embed from Integrations → Website widget or with Revoke a widget deployment. It stops working on the next request, and revocation is permanent. To move a site to a different assistant, create a new embed, replace the widget key in your snippet, then revoke the old one. An embed’s assistant cannot be changed after creation.Limits
- Each visitor has a request budget of 20 requests per minute on each embed, and the embed has a ceiling of 600 requests per minute across all its visitors, both separate from your API traffic. A visitor is counted by the network address their requests come from, so visitors behind one address share their 20. Asking a question and rating the answer takes about three requests. Over budget, requests receive
429with aRetry-Afterheader, and the response carries the cross-origin header for your allowed origin, so code of your own that calls the widget endpoints can read both. - If the rate-limiting service is unavailable, widget requests are refused rather than served without limits.
- Every answer counts against your organisation’s monthly answer allowance. When it is used, a visitor who asks sees “The monthly answer limit for this account has been reached.” and no retry is offered.
- The widget spends those budgets carefully: it checks that the embed is live once per browser tab and reuses the answer for up to 30 minutes, instead of asking on every page view. A change to your branding therefore reaches a tab that is already browsing within 30 minutes, and a new tab at once. Revocation is not delayed by this: it is enforced on every request.
Build your own widget
To build a custom interface instead, call the public widget endpoints from the browser with the widget key and visitor token.If the widget does not appear
A button that never renders is nearly always one of five things: the line is not in the page that was actually served, your platform removed the tag’sdata- attributes, the snippet was edited after it was copied, the page’s origin is not in the embed’s allowed origins, or the embed has been revoked. Start with Check my website under Integrations → Website widget, which settles the first and the fourth; the browser’s developer console names most of the others, because a misconfigured widget logs one message saying what is wrong and renders nothing. Troubleshooting works through each cause, including the case where the widget appears but every question fails.
Next steps
- Customise the widget: its label, position and shortcut, and opening it from your own button.
- Branding: the colours, logo and name the widget shows.
- Coverage gaps: the questions visitors asked that your content could not answer.