Storefront Bot (AI chat widget)
Add Brainerce's AI shopping assistant to any storefront with one line of code. The bot answers product questions, shows recommendation cards, handles cart adds, and escalates to the merchant team when needed.
Add the store's AI shopping assistant to any page with one line, with no props and no config. Everything (name, avatar, colors, greeting, starter questions, capabilities, guardrails) is configured by the merchant in the dashboard under Customers → Storefront Bot, and the widget renders nothing until the bot is switched Live there. Those same settings are also readable and writable over the admin API. See Configure programmatically.
Zero-code embed (any site)
<script src="https://cdn.brainerce.com/bot.js" data-connection-id="vc_abc123" defer></script>Keep the tag exactly this bare, and do not add integrity or crossorigin (the bootstrap is intentionally mutable so merchants never re-paste the tag on releases; it is origin-pinned by your CSP script-src instead).
SDK mount (React / Next.js / any bundler)
import { BrainerceBot } from 'brainerce/bot';
// e.g. in a useEffect or client entry — mounts a floating chat bubble
const bot = await BrainerceBot.mount({ connectionId: 'vc_abc123' });
// later, if needed:
bot?.destroy();mount resolves to null when the bot is switched off or unconfigured for the connection, so it is safe to call unconditionally. If the store's AI credits run out, the widget still mounts but replies with a short "taking a break" message until credits reset.
Mount options
| Option | Required | Description |
|---|---|---|
connectionId | yes | Your vc_* connection id |
baseUrl | no | API origin override (self-hosted / staging) |
target | no | Mount element (defaults to document.body) |
onAddToCart | no | ({ productId, variantId, quantity }) => boolean | Promise<boolean>. Route the widget's cart adds through your own cart so your header count stays in sync. variantId is null for simple products. Return false to make the widget fall back to the product page. |
customerSessionProxyPath | no | A same-origin path (e.g. /api/store, the Next.js template's own BFF proxy) that forwards to the Brainerce API and attaches the shopper's customer-session cookie as a Bearer header. Required for order tracking. See below. |
customerSessionProxyPath: omit it and order tracking silently never works
This is the option most likely to be missed, and its failure mode is invisible.
When it is set, the widget calls ${customerSessionProxyPath}/api/storefront-bot/:connectionId/customer-session to learn whether the shopper is logged in and to obtain a short-lived token, which it then attaches to its normal direct-to-backend /chat call. Streaming is unaffected. It has to go through your origin rather than baseUrl because the session cookie is httpOnly, and a cross-origin request to baseUrl would never carry it.
Omit it and the bot has no way to identify the shopper. The checkOrderStatus tool then answers every order question as a guest (No verified shopper session — cannot look up an order.), forever, for every shopper, including logged-in ones. There is no error: nothing is thrown, nothing is logged to the console, the widget mounts normally, and the Order tracking capability still shows as enabled in the merchant's dashboard. The only symptom is a bot that can never find anybody's order.
So: if the store has customer accounts and you want order tracking to work, wire the proxy. If your site has no such proxy, omit the option entirely. That is a supported configuration, and the bot degrades to guest answers rather than breaking.
Order lookups are additionally scoped to the sales channel the bot is mounted on: a shopper only ever sees orders placed through this connection.
What the bot does
- Answers product questions: searches the catalog, describes items, compares options
- Recommendation cards: image, price, add-to-cart button, in-card variant picker (attribute chips with live price update)
- Cart adds: shopper can say "add the blue one to my cart"; resolves through your
onAddToCarthook →brainerce:bot:add-to-cartCustomEvent → product page fallback - Order tracking. "Where is my order?" is the most common question a storefront bot gets. The bot looks up the shopper's own recent orders and their shipment status, identifying them from their verified session, and it never asks for an order number or email. On by default, and it requires
customerSessionProxyPath(above) to work at all - Escalation. When the question can't be answered from the catalog or store information, the bot opens a "leave a message" contact form that lands in the merchant's Inquiries inbox
- Unmet demand analytics: searches that match nothing are logged for the merchant to see which products shoppers want but can't find
The bot is read-only by design: aside from cart adds the shopper explicitly initiates, it never modifies store data.
Capabilities the merchant can switch off
Five toggles in the dashboard (Customers → Storefront Bot → Studio → Behavior) decide what the bot is allowed to do. They change which tools the model is handed, so a disabled capability is not merely hidden: the bot becomes incapable of it.
| Capability | Dashboard label | Default | What switching it off removes |
|---|---|---|---|
productQa | Product Q&A | On | Catalog search, product lookup and cart adds. The bot can no longer discuss or show products at all |
recommendations | Recommendations | On | Popular-product suggestions (needs productQa too, since without product lookup there is no way to show a result) |
orderTracking | Order tracking | On | checkOrderStatus, covering order and shipment lookups |
returns | Returns & refunds | On | Return-policy and refund guidance from the bot's instructions |
bundleNudges | Bundle nudges | Off | Add-on and bundle suggestions (needs productQa too) |
Escalation is the always-on safety valve and cannot be switched off. Even with every capability disabled, the bot can still hand the shopper to the store team.
Your embed code does not set these and cannot override them; they are read from the merchant's saved settings on every conversation.
Add-to-cart integration
const bot = await BrainerceBot.mount({
connectionId: 'vc_abc123',
onAddToCart: ({ productId, variantId, quantity }) => {
// return true to confirm add, false to fall back to product page
return myCart.add(productId, variantId, quantity);
},
});As an alternative, listen for the CustomEvent anywhere on the page:
window.addEventListener('brainerce:bot:add-to-cart', (e) => {
const { productId, variantId, quantity } = e.detail;
myCart.add(productId, variantId, quantity);
e.preventDefault(); // prevents the product page fallback
});Scaffolds from create-brainerce-store ≥ 1.45 wire onAddToCart for you automatically.
Display & configuration
Display behavior (compact / full-screen / shopper-resizable, position, auto-open, accent color, avatar, greeting, starter questions) is controlled by the merchant in the dashboard under Customers → Storefront Bot. The embed tag never decides display behavior; it only provides the connectionId.
Dashboard configuration (merchant side)
Merchants configure the bot at Customers → Storefront Bot in the Brainerce dashboard:
- Live / Off toggle: the bot renders nothing until switched Live
- Name and avatar: preset avatars or an AI-generated / uploaded image
- Greeting and starter questions: the opening message and quick-tap chips
- Accent color: matches the store brand
- Custom instructions and FAQs: guide the bot's personality and pre-load answers
- Escalation: configure the "leave a message" contact form
Configure programmatically (admin API)
The bot's settings and its conversation inbox are not dashboard-only. With an admin-mode client (apiKey: 'brainerce_*') the SDK exposes five methods over /v1/storefront-bot/*, useful for agencies configuring many stores, or for pulling conversations into your own analytics.
| Method | What it does |
|---|---|
getBotSettings() | Settings for every connection on the store: name, avatar, persona, starter questions, guardrails, capabilities |
updateBotSettings(data) | Create or update one connection's settings. PATCH semantics: only the fields present in data change |
listBotConversations({ salesChannelId, page, limit }) | Paginated conversation inbox, optionally filtered to one connection |
getBotConversation(conversationId) | Full transcript for one conversation, including its summary if one was generated |
summarizeBotConversation(conversationId) | Summarize a conversation on demand and persist it. Threads of 10 messages or fewer are a graceful no-op, with no credits charged |
const admin = new BrainerceClient({ apiKey: 'brainerce_...' });
await admin.updateBotSettings({ salesChannelId: 'vc_abc123', enabled: true });
const { data } = await admin.listBotConversations({ limit: 20 });All five require Admin mode, so a vc_* or storeId client cannot call them. The raw operations are listed under external API v1.
Where the bot is allowed to load
The bot answers only requests that come from the domain configured on the connection. This is checked on every widget call (bootstrap, chat, escalation) against the browser's Origin, and it is the same rule the rest of the storefront API uses.
| Connection | Rule |
|---|---|
| Live | The page's origin must match the connection's domain (exact host or a subdomain of it), or be listed in the connection's additional allowed origins. A domain is required, and a Live connection without one serves nothing. |
| Test, no domain set | Any origin. This is what makes localhost, preview URLs and staging hosts work while you build. |
| Test, domain set | Same rule as Live. |
A blocked origin does not produce an error. The bot simply does not appear. The bootstrap always answers "bot is off" rather than explaining why, so that nobody can probe which connection ids exist. That means the widget silently not rendering has four possible causes and they look identical from the page: the bot is switched off, the plan/credits are exhausted, the connectionId is wrong, or the page's domain is not on the connection. Check the connection's domain in Sales channels first, because it is the one people hit when moving a working storefront to a new host.
Add staging, preview or secondary domains to the connection's allowed origins rather than switching it back to Test.
Server-rendered calls send no Origin at all. A Test connection without a domain accepts them; a Live connection rejects them. Mount the widget client-side, because it is a browser widget and always sends one.
CSP requirements
If your storefront has a Content Security Policy, add:
script-src https://cdn.brainerce.com;
connect-src https://api.brainerce.com;Plan requirement
The Storefront Bot is available on every plan. Usage draws from the store's shared AI credit pool (FREE: 5/day, 30/month). Once exhausted, the widget stays mounted but replies with a short "taking a break" message instead of calling the model, and resumes automatically once credits reset.
App SDK Reference (@brainerce/app-sdk)
Manifest builder, connector / payment / shipping contracts, scopes, events and webhook verification for marketplace apps built on @brainerce/app-sdk.
Storefront MCP
A public, per-channel MCP endpoint that lets AI shopping agents search and read a store's live catalog with structured JSON-RPC calls instead of crawling HTML.