BranderChatWidget
Floating chat widget with customizable trigger button
Import
import { BranderChatWidget, sseStream } from '@brander/sdk';
// Or with specific adapters
import { BranderChatWidget, anthropicStream, openaiStream, geminiStream } from '@brander/sdk';Overview
BranderChatWidget is a floating chat interface that appears on top of your application. It includes:
- Custom Trigger Button: You provide any React element as the trigger
- Floating Popup: Widget appears above your content with optional backdrop
- Flexible Positioning: Choose from 4 corner positions
- Smooth Animations: Configurable fade and slide effects
- Mobile Responsive: Optimized for all screen sizes
Basic Usage (Streaming)
App.tsx
import { BranderChatWidget, sseStream } from '@brander/sdk';
function App() {
return (
<div className="app">
<h1>My Application</h1>
<p>Your main content here...</p>
<BranderChatWidget
betaKey="bux_your_token"
projectId="my-project-id"
onQueryStream={(params) => sseStream("/api/agent", { params })}
position="bottom-right"
>
{/* Custom trigger button */}
<button style={{
padding: '12px 24px',
borderRadius: '50px',
backgroundColor: '#0066FF',
color: 'white',
border: 'none',
cursor: 'pointer'
}}>
Chat with AI
</button>
</BranderChatWidget>
</div>
);
}Props
Required Props
betaKey: string- Your BranderUX API tokenprojectId: string- Your BranderUX project ID- AI Handler (ONE of the following):
onQueryStream: StreamingCallback- Streaming handler (Recommended)onQuery: OnQueryCallback- Non-streaming handler (Alternative)
children: React.ReactElement- Custom trigger button/element
Widget Configuration
position?: "bottom-right" | "bottom-left" | "top-right" | "top-left"
Widget position on screen (default:"bottom-right")offset?: { top?: number; bottom?: number; left?: number; right?: number }
Offset from edges in pixels (default:{ bottom: 24, right: 24 })widgetSize?: { width?: string; height?: string }
Widget popup dimensions (default:{ width: "400px", height: "650px" })
Behavior
defaultOpen?: boolean- Initially open state (default:false)onOpen?: () => void- Callback when widget opensonClose?: () => void- Callback when widget closesshowBackdrop?: boolean- Show backdrop overlay when open (default:true)backdropOpacity?: number- Backdrop opacity 0-1 (default:0.2)closeOnBackdropClick?: boolean- Close when clicking backdrop (default:true)
Styling
zIndex?: number- z-index for widget elements (default:9999)widgetClassName?: string- CSS class for popup containeranimationDuration?: number- Animation duration in ms (default:200)
AI Configuration
variant?: "hybrid" | "classic" | "chat"- Display variant (default:"classic")"hybrid": Full playground with scroll-snapping and query badges"classic": Clean site-focused view with conversation sidebar"chat": Chat-style scrolling with inline messages
Conversation History
conversations?: Conversation[]- Initial conversations to loadactiveConversationId?: string- Currently active conversation IDonConversationsChange?: (state: ConversationsState) => void- Callback for conversation state changes
Positioning Examples
Bottom Right (Default)
<BranderChatWidget
{...props}
onQueryStream={(params) => sseStream("/api/agent", { params })}
position="bottom-right"
offset={{ bottom: 24, right: 24 }}
>
<button>Chat</button>
</BranderChatWidget>Top Left
<BranderChatWidget
{...props}
onQueryStream={(params) => sseStream("/api/agent", { params })}
position="top-left"
offset={{ top: 80, left: 24 }}
>
<button>Support</button>
</BranderChatWidget>Bottom Left with Custom Size
<BranderChatWidget
{...props}
onQueryStream={(params) => sseStream("/api/agent", { params })}
position="bottom-left"
offset={{ bottom: 20, left: 20 }}
widgetSize={{ width: "500px", height: "800px" }}
>
<button>Help</button>
</BranderChatWidget>Full Configuration Example
App.tsx
import { BranderChatWidget, sseStream } from '@brander/sdk';
import { MessageCircle } from 'lucide-react';
function App() {
return (
<div className="app">
<header>
<h1>My SaaS Application</h1>
</header>
<main>
{/* Your main content */}
</main>
<BranderChatWidget
// Required
betaKey="bux_your_token"
projectId="my-project-id"
onQueryStream={(params) => sseStream("/api/agent", { params })}
// Widget Configuration
position="bottom-right"
offset={{ bottom: 24, right: 24 }}
widgetSize={{ width: "450px", height: "700px" }}
// Behavior
defaultOpen={false}
onOpen={() => console.log('Chat opened')}
onClose={() => console.log('Chat closed')}
showBackdrop={true}
backdropOpacity={0.3}
closeOnBackdropClick={true}
// Styling
zIndex={9999}
animationDuration={250}
widgetClassName="custom-chat-widget"
>
{/* Custom trigger button with icon */}
<button
style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
padding: '14px 28px',
backgroundColor: '#0066FF',
color: 'white',
border: 'none',
borderRadius: '50px',
fontSize: '16px',
fontWeight: 600,
cursor: 'pointer',
boxShadow: '0 4px 12px rgba(0, 102, 255, 0.3)',
transition: 'all 0.2s ease'
}}
onMouseEnter={(e) => {
e.currentTarget.style.transform = 'scale(1.05)';
e.currentTarget.style.boxShadow = '0 6px 16px rgba(0, 102, 255, 0.4)';
}}
onMouseLeave={(e) => {
e.currentTarget.style.transform = 'scale(1)';
e.currentTarget.style.boxShadow = '0 4px 12px rgba(0, 102, 255, 0.3)';
}}
>
<MessageCircle size={20} />
Chat with AI
</button>
</BranderChatWidget>
</div>
);
}Alternative: Non-Streaming
App.tsx
import { BranderChatWidget } from '@brander/sdk';
function App() {
return (
<BranderChatWidget
betaKey="bux_your_token"
projectId="my-project-id"
onQuery={async (params) => {
const response = await fetch('/api/ai', {
method: 'POST',
body: JSON.stringify(params)
});
return response.json();
}}
position="bottom-right"
>
<button>Chat</button>
</BranderChatWidget>
);
}Custom Trigger Button Examples
Simple Button
<BranderChatWidget {...props}>
<button className="chat-trigger">
Chat
</button>
</BranderChatWidget>Floating Action Button (FAB)
<BranderChatWidget {...props}>
<button style={{
width: '60px',
height: '60px',
borderRadius: '50%',
backgroundColor: '#1976d2',
color: 'white',
border: 'none',
fontSize: '24px',
cursor: 'pointer',
boxShadow: '0 4px 12px rgba(0, 0, 0, 0.15)'
}}>
💬
</button>
</BranderChatWidget>With MUI Components
import { Fab } from '@mui/material';
import ChatIcon from '@mui/icons-material/Chat';
<BranderChatWidget {...props}>
<Fab color="primary" aria-label="chat">
<ChatIcon />
</Fab>
</BranderChatWidget>Custom Component
const CustomTrigger = () => (
<div style={{
display: 'flex',
alignItems: 'center',
gap: '8px',
padding: '12px 20px',
background: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
color: 'white',
borderRadius: '12px',
cursor: 'pointer',
boxShadow: '0 4px 15px rgba(102, 126, 234, 0.4)'
}}>
<span>🤖</span>
<span style={{ fontWeight: 600 }}>AI Assistant</span>
</div>
);
<BranderChatWidget {...props}>
<CustomTrigger />
</BranderChatWidget>Use Cases
- Customer Support: Add AI-powered chat support to any page
- Help Centers: Provide instant answers without leaving the page
- Sales Assistants: Guide users through product discovery
- Documentation Helper: Answer questions about your product
- Virtual Assistants: Provide personalized user assistance
BranderChatWidget vs Brander
| Feature | BranderChatWidget | Brander |
|---|---|---|
| Integration | Floating widget | Inline embed |
| Trigger Button | Custom (required) | None |
| Position | Configurable (4 corners) | Fixed in layout |
| Backdrop | Yes (optional) | No |
| Best For | Support, help centers | Dashboards, data tools |
| Mobile | Optimized overlay | Responsive layout |