A production-ready React UI kit for building AI chat experiences with the Cuadra AI API
A production-ready React UI kit for building AI chat experiences with the Cuadra AI API, built on top of assistant-ui.
๐ Full Documentation | ๐ Website
- ๐ Ready-to-use chat components - Pre-built thread list, message display, and composer
- ๐จ Beautiful UI - Textured card design with theme support (light/dark/system)
- ๐ Multiple chat modes - Single chat or multi-thread support
- ๐ค Model selection - Fixed model or dynamic model selector
- ๐ฆ Two build formats:
- Library build (ESM/CJS) - For use in React applications
- Widget build (UMD) - For direct browser embedding via script tag
- ๐ Flexible authentication - Bearer token or proxy mode for backend-handled auth
- โก Streaming support - Real-time message streaming via SSE
- ๐งต Thread management - Create, rename, delete, and switch between chat threads
- ๐ i18n ready - Language/locale support
``bash`
npm install @cuadra-ai/uikit
This package requires the following peer dependencies:
`bash`
npm install react react-dom
Note: @assistant-ui/react and @assistant-ui/react-markdown are bundled dependencies and don't need to be installed separately.
The CuadraChat component is the easiest way to get started. It's an all-in-one component that handles everything for you.
Styles are automatically included when you import components from @cuadra-ai/uikit. You don't need to manually import styles unless you're using a custom build setup. If styles don't load automatically, you can manually import them:
`tsx`
import '@cuadra-ai/uikit/styles';
#### Basic Example
`tsx
import { CuadraChat } from '@cuadra-ai/uikit';
function App() {
return (
Note: Model IDs are provided in your Cuadra AI Dashboard. Create and manage your models there, then use the model ID in your code.
#### With Model Selector
`tsx
import { CuadraChat } from '@cuadra-ai/uikit';
import { useState } from 'react';function App() {
const [modelId, setModelId] = useState(null);
return (
baseUrl="https://api.cuadra.ai"
sessionToken="your-session-token"
mode="multiChat"
modelMode="selector"
modelId={modelId || undefined}
onModelChange={setModelId}
/>
);
}
`#### Proxy Mode (Backend Authentication)
When your backend handles authentication, use
proxyUrl instead of baseUrl:`tsx
import { CuadraChat } from '@cuadra-ai/uikit';function App() {
return (
proxyUrl="/api/chat"
mode="multiChat"
modelMode="fixed"
modelId="your-model-id"
/>
);
}
`#### New V2 Props (Recommended)
The new V2 props API groups related options for better organization:
`tsx
import { CuadraChat } from '@cuadra-ai/uikit';function App() {
return (
connection={{
baseUrl: "https://api.cuadra.ai",
sessionToken: "your-session-token",
}}
chat={{
mode: "multiChat",
modelMode: "fixed",
modelId: "your-model-id",
enableReasoning: true,
}}
ui={{
theme: "system",
welcomeTitle: "Welcome to Chat",
welcomeSubtitle: "How can I help you today?",
suggestions: [
{ prompt: "What is Cuadra AI?" },
{ prompt: "How do I get started?" }
],
}}
callbacks={{
onChatCreated: (chatId) => console.log('Chat:', chatId),
onError: (error) => console.error(error),
}}
className="my-custom-class"
/>
);
}
`#### With Context Provider (External Control)
Use
CuadraChatProvider to control the chat from anywhere in your component tree:`tsx
import { CuadraChat, CuadraChatProvider, useCuadraChat } from '@cuadra-ai/uikit';function ChatControls() {
const { controls, isReady } = useCuadraChat();
return (
onClick={() => controls?.sendMessage('Hello!')}
disabled={!isReady}
>
Send Hello
);
}
function App() {
return (
connection={{ baseUrl: "https://api.cuadra.ai" }}
chat={{ modelId: "your-model-id" }}
/>
);
}
`#### With Error Boundary
CuadraChat includes built-in error handling:
`tsx
import { CuadraChat } from '@cuadra-ai/uikit';function App() {
return (
connection={{ baseUrl: "https://api.cuadra.ai" }}
chat={{ modelId: "your-model-id" }}
errorFallback={(error, reset) => (
Something went wrong: {error.message}
)}
/>
);
}
`#### Legacy Props (Still Supported)
`tsx
import { CuadraChat } from '@cuadra-ai/uikit';function App() {
return (
baseUrl="https://api.cuadra.ai"
sessionToken="your-session-token"
mode="multiChat"
modelMode="fixed"
modelId="your-model-id"
className="my-custom-class"
showThemeToggle={true}
theme="system"
language="en"
welcomeTitle="Welcome to Chat"
welcomeSubtitle="How can I help you today?"
extraTopPadding="2rem"
suggestions={[
{ prompt: "What is Cuadra AI?" },
{ prompt: "How do I get started?" },
{ prompt: "Show me examples" }
]}
onChatCreated={(chatId) => {
console.log('Chat created:', chatId);
}}
onThreadIdUpdate={(oldId, newId) => {
console.log('Thread updated:', oldId, '->', newId);
}}
onError={(error) => {
console.error('Error:', error);
}}
/>
);
}
`$3
The widget build allows you to embed the chat interface directly in any HTML page without a build step.
#### Basic HTML Setup
`html
Cuadra Chat
`#### With Data Attributes (Auto-initialization)
`html
data-base-url="https://api.cuadra.ai"
data-session-token="your-session-token"
data-mode="multiChat"
data-model-mode="fixed"
data-model-id="your-model-id"
style="height: 100vh; width: 100%;">
`
#### Proxy Mode (Widget)
`html
`
For detailed widget API documentation, see the full documentation.
| Prop Group | Prop | Type | Description |
|------------|------|------|-------------|
| connection | baseUrl | string | Cuadra API base URL |proxyUrl
| | | string | Proxy URL for backend auth |sessionToken
| | | string \| null | Bearer token |chat
| | mode | 'singleChat' \| 'multiChat' | Chat mode (default: 'multiChat') |modelMode
| | | 'fixed' \| 'selector' | Model selection mode (default: 'fixed') |modelId
| | | string | Model ID from dashboard |systemPrompt
| | | string | System prompt |ephemeral
| | | boolean | Auto-delete chats on close |enableReasoning
| | | boolean | Enable thinking output |enableAttachments
| | | boolean | Enable file attachments |ui
| | theme | 'light' \| 'dark' \| 'system' | Theme mode (default: 'system') |showThemeToggle
| | | boolean | Show toggle (default: true) |welcomeTitle
| | | string | Welcome screen title |welcomeSubtitle
| | | string | Welcome screen subtitle |suggestions
| | | Array | Welcome screen suggestions |inputPlaceholder
| | | string | Input field placeholder |callbacks
| | onChatCreated | (id: string) => void | Called when chat created |onError
| | | (error: Error) => void | Error callback |onModelChange
| | | (id: string) => void | Model change callback |errorFallback
| | | ReactNode \| Function | Custom error UI |className
| | | string | Container CSS class |
| Hook | Description |
|------|-------------|
| useCuadraChat() | Access chat controls from context (requires CuadraChatProvider) |useCuadraChatOptional()
| | Same as above, returns null if no provider |
| Utility | Description |
|---------|-------------|
| sanitizeSystemPrompt() | Remove injection patterns from prompts |isValidUrl()
| | Validate URL uses http/https |validateBaseUrl()
| | Validate API base URL with details |generateSecureUUID()
| | Crypto-secure UUID generation |createAttachmentAdapter()
| | Create file attachment adapter with validation |
| Prop | Type | Required | Default | Description |
|------|------|----------|---------|-------------|
| baseUrl | string | Yes* | - | Cuadra API base URL (e.g., 'https://api.cuadra.ai') |proxyUrl
| | string | Yes* | - | Proxy URL for backend-handled auth (e.g., '/api/chat') |sessionToken
| | string \| null | No | null | Bearer token for authentication |mode
| | 'singleChat' \| 'multiChat' | No | 'multiChat' | Chat mode |modelMode
| | 'fixed' \| 'selector' | No | 'fixed' | Model selection mode |modelId
| | string | Yes** | - | Model ID from dashboard.cuadra.ai (required if modelMode='fixed') |onModelChange
| | (modelId: string) => void | No | - | Callback when model changes (selector mode) |ephemeral
| | boolean | No | false | Create temporary chats that auto-delete |systemPrompt
| | string | No | - | System prompt for the assistant |initialThreadId
| | string | No | - | Load existing thread (multiChat mode) |className
| | string | No | - | Container className for styling |showThemeToggle
| | boolean | No | true | Show theme toggle button |theme
| | 'light' \| 'dark' \| 'system' | No | 'system' | Initial theme |language
| | string | No | - | Language/locale for i18n (e.g., 'en', 'es', 'fr') |welcomeTitle
| | string | No | - | Welcome screen title |welcomeSubtitle
| | string | No | - | Welcome screen subtitle |extraTopPadding
| | string | No | - | Extra top padding for thread viewport (e.g., '1rem', '2rem') |suggestions
| | Array<{ prompt: string }> | No | - | Suggestions to show in welcome screen |onError
| | (error: Error) => void | No | - | Error callback |onChatCreated
| | (chatId: string) => void | No | - | Callback when chat is created |onThreadIdUpdate
| | (oldId: string, newId: string) => void | No | - | Callback when thread ID updates |
\* Either baseUrl or proxyUrl is required modelMode='fixed'
\** Required if
MIT License
Third-Party Licenses: This package bundles code from third-party libraries in the widget build. The THIRD_PARTY_LICENSES.md` file is included in the published package for attribution and license information.
For issues and questions:
- ๐ Documentation - Full API reference and guides
- ๐ Website - Learn more about Cuadra AI
- ๐ง Support: support@cuadra.ai