Website widget
Add a floating, talking avatar to any website with one script tag.
To add a talking AI avatar to a website, paste one <script> tag before </body>. It works on any page, in any framework, with no npm package and no server to run.
What you’ll build
A talking avatar in the corner of your website. Visitors open it, allow the microphone and talk to it; it answers out loud with its lips in sync.
You need:
- a website you can add a
<script>tag to, served over HTTPS (orhttp://localhostwhile you build); - an agent code:
A23WJF0199(thewise-pupsample) or your own agent’s.
Steps
6 steps
Pick the agent
Use the
wise-pupsample (agent codeA23WJF0199) while you build. For your own agent, keep Let anyone talk without signing in on in the agent’s Share Agent dialog: the widgets open the agent’s public link, and its sessions bill your account.Sample agents end after 1 minute. bitHuman pays for sessions on its sample and showcase agents, such as
wise-pup, so each one ends about a minute after the avatar appears (or 5 minutes after it starts, if the avatar never appears), with an end-of-demo card.Your own agent has no visitor limits by default. Chats run until the visitor closes them and bill by the second, talking or idle; set a limit for a kiosk that runs all day. You can set a per-session and a daily limit. Sessions start only when the visitor taps, so a page view costs nothing.
Set them in the Console: open the agent’s Embed Agent tab, then Visitor limits, to set a daily limit in minutes for all visitors together, a limit per chat (5 to 60 minutes, or no limit) and an optional list of allowed websites. When the daily limit is used up, new visitors see a Resting for Today card until the next day.
Expected
https://bithuman.ai/A23WJF0199opens the avatar in a browser tab.Add the floating widget
Paste this before
</body>:<script src="https://www.bithuman.ai/widgets/bithuman-gadget.js"></script> <script> BitHumanGadget.init({ agentUrl: "https://bithuman.ai/A23WJF0199?deployment=gadget&render=auto", position: "bottom-right", buttonText: "Talk to us", }); </script>render=auto: web render by default; devices that can’t web-render use cloud render automatically.render=cloudforces cloud.Expected
A button in the bottom-right corner. Select it: the avatar opens in a floating frame you can drag and resize, asks for the microphone, and answers when you speak.
Or add the chat widget
The chat widget opens a side panel where visitors type, talk, or switch to video:
<script src="https://www.bithuman.ai/widgets/bithuman-chat-widget.js"></script> <script> BitHumanChat.init({ agentUrl: "https://bithuman.ai/A23WJF0199?render=auto", defaultChatMode: "text", welcomeMessage: "Hi! How can I help?", }); </script>Expected
A floating card in the corner. Opening it shows the panel with the welcome message; the mode switch moves between text, voice and video.
Make the AI character stand on your page
Add
transparent: trueand the character’s backdrop is removed, so it floats over your page with no box around it. Try it with theBiscuitsample (agent codeG10BISCUIT):<script src="https://www.bithuman.ai/widgets/bithuman-gadget.js"></script> <script> BitHumanGadget.init({ agentUrl: "https://bithuman.ai/G10BISCUIT?deployment=gadget&render=auto", transparent: true, size: 360, }); </script>Expected
The button opens Biscuit standing directly on your page, with your page's background around it.
Transparent mode works for AI characters filmed or generated on a plain green backdrop. For any other character the frame stays as it is, so turning it on never breaks a page. In your own
<iframe>, addtransparent=1to the embed URL instead.Load it in React or Next.js
In Next.js, load the script with
next/scriptand callinitwhen it has loaded:"use client"; import Script from "next/script"; declare global { interface Window { BitHumanGadget?: { init: (options: Record<string, unknown>) => void } } } export function AvatarWidget({ code }: { code: string }) { return ( <Script src="https://www.bithuman.ai/widgets/bithuman-gadget.js" strategy="afterInteractive" onLoad={() => window.BitHumanGadget?.init({ agentUrl: `https://bithuman.ai/${code}?deployment=gadget&render=auto` })} /> ); }Render
<AvatarWidget code="A23WJF0199" />once, in your root layout. In other React apps, add the two<script>tags to the page’s HTML, or put the web embed in an<iframe>(Web).Expected
The widget's button appears on every page of the app. A second
initcall is ignored, so a re-render does not add a second widget.Give it your persona and model
The widget runs the agent’s managed conversation, so the persona and the model are settings on the agent, not code on your page. Set the persona as the agent’s
system_prompt(Persona). To answer with your own model, connect any OpenAI-compatible endpoint with Providers and point the agent’sllmat it.Expected
The next session answers in the new persona, with your model. Nothing on your page changed.
All steps done. Next: make it your own.
How it works
The script adds a button to your page. Opening it loads the web embed for your agent in a frame. With render=auto the avatar renders in the visitor’s tab where the device can; otherwise it renders in the bitHuman cloud, in the US, and streams to the visitor. With the web embed, the conversation runs on bitHuman’s servers, even when the avatar renders in the tab.
4 credits per minute of active session time for Essence 2 and Expression 2, about $0.04 a minute at the top-up rate of $1 = 100 credits. Managed voice chat bills 10 credits per minute, all-inclusive: the avatar is part of it. Billing: How billing works. Every rate: Pricing and credits.
Make it your own
The embed dialog in the Console writes these options for you. agentUrl is required; the rest are optional.
Floating widget (BitHumanGadget.init):
| Option | Values |
|---|---|
agentUrl | https: (render=cloud forces cloud render) |
theme | light (default) or dark |
position | bottom-right (default), bottom-left, top-right, top-left, center |
size | the frame’s starting size in pixels (default 200) |
transparent | true removes a green-screen backdrop, so the avatar stands on your page (Transparent background) |
keyColor, keySimilarity, keySmoothness, keySpill, keyErode, keyer | fine-tune transparent (Transparent background) |
buttonStyle | pill (default; image and text), circle, square |
buttonText | the button label, for pill (default “Chat”) |
imageUrl | the button’s image (default: the bitHuman logo) |
frameStyle | rounded (default), circular, portrait (9:16) |
draggable, resizable | true (default) or false |
minSize, maxSize | size limits in pixels (defaults 50 and 400) |
margin | distance from the screen edge in pixels (default 60) |
autoLoad | true opens the avatar when the page loads (default false) |
greetingLanguage | auto (default; from the page’s <html lang>) or a code such as es |
greetingMessage | the first thing the avatar says |
Chat widget (BitHumanChat.init):
| Option | Values |
|---|---|
agentUrl | https: (render=cloud forces cloud render) |
theme | light (default) or dark |
themeColor | blue (default), purple, green, red, orange, teal, pink, indigo |
position | bottom-right (default) or bottom-left |
fabStyle | preview (default; a card with the avatar), bar, circle |
fabText, fabSubtext | the button’s label and the line under it |
fabSize | the circle’s diameter in pixels (default 60) |
imageUrl | the image on the button (default: the bitHuman logo) |
attentionPulse | true (default) pulses rings around the avatar |
topBanner, topBannerText, topBannerQuestions | a banner across the top of the page, its headline and its question chips |
defaultChatMode | text (default), voice, video |
allowModeSwitch | true (default) lets visitors switch modes |
autoLoad | true opens the panel when the page loads (default false) |
headerTitle | the panel title (default: the agent’s name) |
welcomeMessage | the first message in the panel |
suggestedQuestions | starter questions in the panel |
teaserEnabled, teaserMessage, teaserDelay, teaserAutoHide | a bubble shown after a delay and hidden again, in milliseconds (default on, 2200, 12000) |
expandedWidth | the panel’s width on a desktop, in pixels (default 420) |
margin, zIndex | distance from the edge in pixels (default 20), and stacking order (default 99999) |
greetingLanguage, greetingMessage | as for the floating widget |
For a private agent, or your own layout, use the web embed in an <iframe> with an embed token instead (Web).
Transparent background
transparent: true (Make the AI character stand on your page) removes a plain green backdrop, so the AI character stands right on your page with no box around it.

When it applies. The character’s backdrop must be one even green, as it is for the showcase characters Biscuit (G10BISCUIT) and Marmalade (G06MARMALAD). In the Console, the embed dialog suggests the option when your character’s picture stands on a green backdrop.
The visitor’s browser looks at the edges of the first frames. When they are one saturated colour, it removes that colour from every frame; when they are not (a photo backdrop, a room, a grey wall), it keeps the normal frame, so the option never damages a character. The green is removed in the browser, so nothing extra is sent over the network. A browser without WebGL 2 shows the normal frame.
Tuning. The defaults suit most green backdrops. Each option below is also a query parameter of the web embed URL (in brackets), for an <iframe> with transparent=1:
| Option | Values |
|---|---|
keyColor (keyColor) | the backdrop colour, such as 00b140; default: measured from the video. Setting it also skips the edge check |
keySimilarity (similarity) | how close to the key a colour must be to disappear, 0.01 to 0.5 (default 0.08) |
keySmoothness (smoothness) | the width of the soft edge, 0.001 to 0.5 (default 0.08) |
keySpill (spill) | how strongly green light on the character’s edges is removed, 0 to 1 (default 0.8) |
keyErode (erode) | how far the edge is pulled in, 0 to 1 (default 0.5) |
keyer (keyer) | classic uses the earlier, simpler keying (default: the current one, with smoothed edges and only the central character kept) |
Troubleshooting
| Symptom | Fix |
|---|---|
Nothing appears, and the browser console says agentUrl is required | Pass agentUrl to init. |
| The microphone never activates | Serve the page over HTTPS, or http: while you build. |
The frame shows Embedding is disabled for this agent | Turn Let anyone talk without signing in back on in the agent’s Share Agent dialog. |
The frame shows Agent not found | The agent code is wrong: copy it from the agent’s Embed Agent dialog in the Console. |
| The frame shows a browser error page | Remove the Cross-Origin-Embedder-Policy header from your page. |
| The console says the widget is already initialized | Call init once per page. |
| The session ends after a minute with That’s the end of this demo | The widget points at a bitHuman sample agent, whose sessions end after about a minute. Point agentUrl at your own agent. |
| A visitor’s chat ends early, or new visitors see Resting for Today | A visitor limit you set on the agent: a limit per chat, or the daily limit for all visitors (it resets the next day). There are no limits by default; change or remove them in the agent’s Embed Agent tab, Visitor limits. |
| The avatar says Voice is off on this site | Your own <iframe> is missing allow="microphone". Add it, as in the Web embed. |