Chatbot Overview
This page covers the ways to add your BIAB chatbot to an externally-hosted
site — your own site, your framework, your hosting — through the
@biab-dev/sdk.
This is about the chatbot on your own, externally-hosted site, connected through the SDK. The chatbot that appears on a site built with BIAB's internal Site Builder is placed and managed inside the builder itself — you don't need the SDK for it.
In every case the chatbot is configured first in your BIAB dashboard — its system prompt, knowledge base, model, live front-desk handoff, file-upload entitlement, and email capture. The SDK never re-implements any of that; it renders (or hands you the data for) a chat whose brain already lives in BIAB. What changes between approaches is how much of the UI you build yourself.
There are three ways to include it, from zero-effort to total control:
| Approach | Where it renders | You build | Reach for it when |
|---|---|---|---|
<Chatbot> | A BIAB-hosted iframe | Nothing | You want the fastest possible drop-in and don't need it to match your design system exactly. |
<ChatbotInline> | Your DOM, styled default | Styling only (optional) | You want it to live in your page (layout, SEO) and match your look — without writing chat logic. |
useChatbot() | Your DOM, your markup | The entire UI | You need total control over every pixel and interaction. |
All three authenticate the same way — a publishable API key scoped to your org — and all three talk to the same package API, so the chatbot behaves identically no matter which you choose. The only difference is how much markup you own.
1. <Chatbot> — the hosted iframe drop-in
The fastest integration. BIAB renders the entire chat experience — bubbles, input, the live front-desk presence strip, inline forms, and file uploads — inside a sandboxed iframe on your page. You write no chat UI and get every feature automatically, including ones added later (you inherit them on your next page load, with no SDK bump).
import { Chatbot } from "@biab-dev/sdk/react"
export function SupportWidget() {
return (
<Chatbot
apiKey={process.env.NEXT_PUBLIC_BIAB_KEY!}
baseUrl="https://app.businessdash.com"
title="Assistant"
style={{ height: 600 }}
onAssistantMessage={(text) => console.log("bot:", text)}
/>
)
}
Expected behavior
- Renders an iframe pointing at BIAB's hosted chatbot page; the SDK mints a short-lived signed session token for you.
- File uploads, email capture, live front-desk handoff, and inline forms all work out of the box — they're part of the hosted UI and respect the same org settings + entitlements described below.
- You can react to events with
onEvent/onAssistantMessage, but you cannot restyle the inside of the iframe. UseclassName/styleto size and place the frame; supplyloadingFallback/errorFallbackfor the surrounding states.
Because the UI is hosted, the <Chatbot> iframe is the only surface that
picks up new chatbot features without updating your @biab-dev/sdk
version.
2. <ChatbotInline> — the in-DOM component
Renders the chat in your own DOM (no iframe), so it participates in your
page layout, your scroll, and your bundle. It ships a polished default theme out
of the box, and everything is restylable — the defaults are
zero-specificity :where() rules keyed to data-slot attributes, so any
classNames you pass already win, and accent/surface colors read from the
--biab-chatbot-accent / --biab-chatbot-bg CSS variables. For full control of
a slot, pass a renderMessage / renderPresenceStrip render-prop.
import { ChatbotInline } from "@biab-dev/sdk/react"
export function InPageChat() {
return (
<ChatbotInline
apiKey={process.env.NEXT_PUBLIC_BIAB_KEY!}
baseUrl="https://app.businessdash.com"
welcomeMessage="Hi! How can we help?"
classNames={{ root: "h-[600px] rounded-2xl border" }}
/>
)
}
Expected behavior
- The chat lives in your DOM — better for layout, theming, and SEO than an iframe.
- File uploads show a paperclip + a staged preview when the org has the
chat.file_uploadsentitlement (the component readsgetConfig()for you); the file uploads and posts with the text on send. - Email capture is honored automatically:
"request"shows a skippable ask,"require"blocks the first message until an email is given. - Live front-desk presence is polled (
availabilityPollMs, default 30s) and rendered as a presence strip; inline forms surface in place. - Set
unstyledto opt out of the default theme entirely and start from bare markup.
3. useChatbot() — the headless hook
When you want to build 100% of the UI yourself, the hook gives you the state and actions and nothing else. This is the most work and the most control.
import { useChatbot } from "@biab-dev/sdk/react"
function MyChat() {
const {
messages, send, isPending, error,
availability, getConfig, getForm, submitForm, uploadFile,
} = useChatbot({
apiKey: process.env.NEXT_PUBLIC_BIAB_KEY!,
baseUrl: "https://app.businessdash.com",
})
// …render `messages`, call `send(text)`, etc.
}
Expected behavior
send(text)runs the org's chatbot (system prompt + knowledge base + model) and appends the reply tomessages;availability+refreshAvailability()drive a "Talk to a person" CTA.- A
show_formaction resolves throughgetForm(slug)→ render →submitForm(slug, …)(which carries the transcript). uploadFile({ sessionId, file })presigns a direct-to-R2 upload (gated by thechat.file_uploadsentitlement) and returns a{ url, name, type, size }ref you attach to your own message UI.- Nothing is rendered for you — you own every bubble, the composer, uploads, and the email gate.
Behaviors shared by every approach
These are configured in the dashboard and apply to all three surfaces:
- Auth — a publishable, org-scoped API key. No secrets ship to the browser; the key only unlocks the surfaces you've entitled.
- File uploads — gated by the
chat.file_uploadsentitlement and exposed asgetConfig().fileUploadsEnabled. The iframe and<ChatbotInline>surface the affordance for you; with the hook you calluploadFileyourself. Visitor files land in the org'schatUploadsFiles & Media folder (2-day TTL unless saved), capped at 7 MB and 5 files/hour per chat, with active-content types refused. - Email capture —
getConfig().emailCaptureModeis"off" | "request" | "require". Captured emails are stored with the conversation (and uploads) for provenance. - Live front-desk — when the org is on a plan with live handoff,
availabilityreports staff presence + a wait-time hint so you can offer "Talk to a person." - Inline forms — the bot can recommend a dashboard form mid-conversation;
the iframe and
<ChatbotInline>render it in place, and the hook hands you theshow_formaction to render yourself.
Start with <Chatbot> to ship in minutes. Move to <ChatbotInline>
when you want it in your DOM and on-brand. Drop to useChatbot() only when
you need to own the whole interface.