Skip to main content

Installation

npm install @cuadra-ai/uikit
Requires React 18+. Styles are bundled—no additional CSS imports needed.

Quick Start

import { CuadraChat } from '@cuadra-ai/uikit';

function App() {
  return (
    <div style={{ height: '100vh' }}>
      <CuadraChat
        connection={{
          baseUrl: "https://api.cuadra.ai",
          sessionToken: "your-session-token"
        }}
        chat={{ modelId: "your-model-id" }}
      />
    </div>
  );
}
Get your model ID from DashboardModels.

Props

Connection

PropTypeDescription
baseUrlstringAPI URL (https://api.cuadra.ai)
proxyUrlstringBackend proxy URL (alternative to baseUrl)
sessionTokenstringJWT session token

Chat

PropTypeDefaultDescription
modelIdstringModel ID (required if modelMode='fixed')
mode'singleChat' | 'multiChat''multiChat'Single or multi-thread
modelMode'fixed' | 'selector''fixed'Allow model switching
systemPromptstringOverride system prompt
ephemeralbooleanfalseAuto-delete chats
enableReasoningbooleanfalseShow AI thinking
enableAttachmentsbooleanfalseFile uploads

UI

PropTypeDefaultDescription
theme'light' | 'dark' | 'system''system'Color scheme
showThemeTogglebooleantrueTheme toggle button
welcomeTitlestringWelcome screen heading
suggestions{prompt: string}[]Pre-made prompts
inputPlaceholderstringInput field placeholder

Callbacks

PropTypeDescription
onChatCreated(id: string) => voidNew chat created
onError(error: Error) => voidError occurred
onModelChange(id: string) => voidModel changed

Examples

With Suggestions

<CuadraChat
  connection={{ baseUrl: "https://api.cuadra.ai", sessionToken: token }}
  chat={{ modelId: "model_abc" }}
  ui={{
    welcomeTitle: "How can I help?",
    suggestions: [
      { prompt: "What can you do?" },
      { prompt: "Show me examples" }
    ]
  }}
/>

Model Selector

<CuadraChat
  connection={{ baseUrl: "https://api.cuadra.ai", sessionToken: token }}
  chat={{ modelMode: "selector" }}
  callbacks={{ onModelChange: (id) => console.log('Model:', id) }}
/>

Proxy Mode (Production)

Route requests through your backend to hide tokens:
<CuadraChat
  connection={{ proxyUrl: "/api/chat" }}
  chat={{ modelId: "model_abc" }}
/>
Your backend handles authentication and forwards to Cuadra AI.

External Controls

import { CuadraChat, CuadraChatProvider, useCuadraChat } from '@cuadra-ai/uikit';

function SendButton() {
  const { controls, isReady } = useCuadraChat();
  return (
    <button onClick={() => controls?.sendMessage('Hello!')} disabled={!isReady}>
      Send
    </button>
  );
}

function App() {
  return (
    <CuadraChatProvider>
      <SendButton />
      <CuadraChat connection={{...}} chat={{...}} />
    </CuadraChatProvider>
  );
}

Theming

Override CSS variables:
:root {
  --cuadra-primary: #6366f1;
  --cuadra-background: #ffffff;
  --cuadra-text: #1f2937;
}

[data-theme="dark"] {
  --cuadra-primary: #818cf8;
  --cuadra-background: #111827;
  --cuadra-text: #f9fafb;
}

Widget Mode (No Build)

Embed via script tag for non-React sites:
<div id="cuadra-chat" style="height: 100vh;"></div>
<link rel="stylesheet" href="https://unpkg.com/@cuadra-ai/uikit/dist/widget/cuadra-uikit.css">
<script src="https://unpkg.com/@cuadra-ai/uikit/dist/widget/cuadra-uikit.umd.js"></script>
<script>
  CuadraUIKit.init({
    baseUrl: 'https://api.cuadra.ai',
    sessionToken: 'your-token',
    modelId: 'your-model-id'
  });
</script>

FAQ

Do I need a backend?

For production: yes. Never expose session tokens in client-side code. Use proxyUrl to route requests through your backend.

Does it support SSR?

The component is client-side only. Use dynamic imports with ssr: false in Next.js:
const CuadraChat = dynamic(() => import('@cuadra-ai/uikit').then(m => m.CuadraChat), { ssr: false });

Can I customize the message rendering?

Not currently. The UI Kit provides opinionated styling. For full control, use the Chat API directly with your own components.

How do I handle authentication?

Get session tokens from your auth system (Stytch B2B) and pass to the sessionToken prop. Tokens refresh automatically with your auth flow.