Getting Started NPM SDK (React / Next.js) Install @docimal/chatbot from npm and embed the chatbot natively in React and Next.js applications. Supports App Router, Pages Router, and the useChatbot() hook.
npm install @docimal/chatbot
Installation Install @docimal/chatbot using your preferred package manager. React ≥ 17 is required as a peer dependency.
npm install @docimal/chatbotExport Import from Description DocimalChatbot@docimal/chatbotReact component — floating chat widget useChatbot@docimal/chatbotHook — imperatively open/close the widget DocimalChatbotIframe@docimal/chatbot/iframeReact component — iframe-isolated widget
React (CRA / Vite) Import DocimalChatbot and render it anywhere in your component tree — typically in your root App component so it persists across route changes.
// App.tsx (or any component)
import { DocimalChatbot } from '@docimal/chatbot';
export default function App() {
return (
<>
{/* Your app content */}
<DocimalChatbot
apiKey="dcml_pk_YOUR_API_KEY"
apiBaseUrl="https://api.docimal.site/agents"
user={{
id: 'user_123',
email: 'user@example.com',
name: 'John Doe',
}}
options={{
position: 'bottom-right',
startOpen: false,
persistSession: true,
}}
theme={{
primaryColor: '#6366f1',
fontFamily: 'Inter, sans-serif',
borderRadius: '12px',
headerStyle: 'colored',
}}
onReady={() => console.log('Chatbot ready')}
onMessage={(msg) => console.log('Message:', msg)}
/>
</>
);
}Tip: The widget is SSR-safe in React (CRA / Vite). No special configuration needed — it uses typeof window !== 'undefined' guards internally.
Next.js App Router Always use ssr: false — the widget uses window, localStorage, and socket.io, which are not available in the Node.js server environment.
Basic setup in app/layout.tsx // app/layout.tsx
import dynamic from 'next/dynamic';
// IMPORTANT: ssr: false is required — the widget uses window, localStorage, and socket.io
const DocimalChatbot = dynamic(
() => import('@docimal/chatbot').then((m) => m.DocimalChatbot),
{ ssr: false }
);
export default function RootLayout({ children }: { children: React.ReactNode }) {
return (
<html lang="en">
<body>
{children}
<DocimalChatbot
apiKey="dcml_pk_YOUR_API_KEY"
apiBaseUrl="https://api.docimal.site/agents"
options={{ position: 'bottom-right', persistSession: true }}
theme={{ primaryColor: '#6366f1' }}
/>
</body>
</html>
);
}With authenticated user session If you use NextAuth, Clerk, or a custom auth solution, pass the server-side session data directly to the widget:
// app/layout.tsx — with server-side user session
import { auth } from '@/lib/auth'; // your auth helper
import dynamic from 'next/dynamic';
const DocimalChatbot = dynamic(
() => import('@docimal/chatbot').then((m) => m.DocimalChatbot),
{ ssr: false }
);
export default async function RootLayout({ children }: { children: React.ReactNode }) {
const session = await auth();
return (
<html lang="en">
<body>
{children}
{session?.user && (
<DocimalChatbot
apiKey={process.env.NEXT_PUBLIC_DOCIMAL_API_KEY!}
apiBaseUrl="https://api.docimal.site/agents"
user={{
id: session.user.id,
email: session.user.email,
name: session.user.name,
}}
options={{ persistSession: true }}
/>
)}
</body>
</html>
);
}Next.js Pages Router Add the widget to pages/_app.tsx so it persists across all pages without re-mounting on navigation.
// pages/_app.tsx
import type { AppProps } from 'next/app';
import dynamic from 'next/dynamic';
const DocimalChatbot = dynamic(
() => import('@docimal/chatbot').then((m) => m.DocimalChatbot),
{ ssr: false }
);
export default function App({ Component, pageProps }: AppProps) {
return (
<>
<Component {...pageProps} />
<DocimalChatbot
apiKey="dcml_pk_YOUR_API_KEY"
apiBaseUrl="https://api.docimal.site/agents"
options={{ position: 'bottom-right', persistSession: true }}
theme={{ primaryColor: '#6366f1' }}
/>
</>
);
}useChatbot() Hook Control the widget programmatically from any component in your app — no prop drilling required. The hook dispatches custom window events that DocimalChatbot listens for internally.
Method Description open()Open the chat window and clear the unread count. close()Close the chat window.
Open from a nav button // NavBar.tsx — open/close the widget from anywhere
import { useChatbot } from '@docimal/chatbot';
export function NavBar() {
const { open, close } = useChatbot();
return (
<nav>
<button onClick={open}>Need Help?</button>
</nav>
);
}Open from a page CTA // ProductPage.tsx — open chatbot on CTA click
import { DocimalChatbot, useChatbot } from '@docimal/chatbot';
export function ProductPage() {
const { open } = useChatbot();
return (
<div>
<h1>Product Title</h1>
<button
onClick={open}
className="btn-primary"
>
Ask AI about this product
</button>
{/* Widget must be in the same React tree */}
<DocimalChatbot
apiKey="dcml_pk_YOUR_API_KEY"
apiBaseUrl="https://api.docimal.site/agents"
options={{ position: 'bottom-right' }}
/>
</div>
);
}Note: The DocimalChatbot component must be rendered in the same React tree (or a parent tree) for useChatbot() to work, since the hook dispatches window events that the component listens for.
Iframe Component DocimalChatbotIframe renders the chatbot inside an <iframe> for full CSS and JavaScript isolation. Ideal when you want a dedicated chat panel, or need to avoid any style conflicts with your app.
React import { DocimalChatbotIframe } from '@docimal/chatbot/iframe';
export function SupportPage() {
return (
<div className="flex h-screen">
<main className="flex-1">
{/* Your page content */}
</main>
{/* Sidebar chatbot panel */}
<aside className="w-[400px] border-l">
<DocimalChatbotIframe
apiKey="dcml_pk_YOUR_API_KEY"
chatbotId="YOUR_CHATBOT_ID"
baseUrl="https://api.docimal.site"
primaryColor="#6366f1"
width="100%"
height="100%"
onReady={() => console.log('iframe ready')}
onMessage={(msg) => console.log('message:', msg)}
onError={(err) => console.error('error:', err)}
/>
</aside>
</div>
);
}Next.js // Next.js — import with dynamic + ssr: false
import dynamic from 'next/dynamic';
const DocimalChatbotIframe = dynamic(
() => import('@docimal/chatbot/iframe').then((m) => m.DocimalChatbotIframe),
{ ssr: false }
);Props Reference DocimalChatbot from @docimal/chatbot Core Prop Type Default Description apiKeystring— Required. Your public API key from the dashboard.apiBaseUrlstringhttps://api.docimal.site/agentsAPI endpoint. Override for self-hosted deployments. chatbotIdstring— Specify if your workspace has multiple agents.
User Identity user Field Type Description user.idstringUnique user ID from your system. user.emailstringUser email — also used as visitor ID for session isolation. user.namestringDisplay name shown in conversations. user.phonestringUser's phone number. user.customAttributesRecord<string, any>Custom key-value pairs (e.g. plan, company, role).
Widget Options options Prop Type Default Description positionstringbottom-right'bottom-right' | 'bottom-left' | 'inline' startOpenbooleanfalseAutomatically open the chat on page load. persistSessionbooleanfalseKeep session across page reloads (localStorage). showBrandingbooleantrueShow "Powered by Docimal" in the footer.
Theme theme Prop Type Description mode'light' | 'dark' | 'auto'Color theme. 'auto' follows system preference. primaryColorstringBrand color hex (e.g. '#6366f1'). fontFamilystringCSS font-family for the entire widget. borderRadiusstringBorder radius of the widget container (e.g. '12px'). headerStyle'light' | 'colored''colored' fills the header with primaryColor. messageStyle'plain' | 'colored''colored' tints assistant message bubbles. inputStylestring'default' | 'inside' | 'rounded' | 'inside-rounded' | 'minimal'
Event Callbacks Callback Signature Description onReady() => voidWidget is fully loaded and ready. onOpen() => voidChat window opened. onClose() => voidChat window closed. onMessage(msg: ChatMessage) => voidNew message (user or assistant). onError(err: Error) => voidConnection or runtime error.
DocimalChatbotIframe from @docimal/chatbot/iframe Prop Type Default Description apiKeystring—Required. Your public API key. chatbotIdstring—Required. The chatbot ID to embed. baseUrlstringhttps://api.docimal.siteBackend API base URL. embedOriginstringhttps://app.docimal.siteOrigin of the embed page (for postMessage security). primaryColorstring—Brand color hex for the iframe widget. widthstring | number400pxIframe width. heightstring | number600pxIframe height. classNamestring—CSS class applied to the iframe element. styleCSSProperties—Inline style applied to the iframe element. onReady() => void—Fired when the iframe widget is ready. onMessage(msg: unknown) => void—Fired on each message from the iframe. onError(err: string) => void—Fired on error events from the iframe.
TypeScript All types are bundled with the package — no @types/ package needed.
import type {
ChatbotEmbedProps,
ChatbotTheme,
ChatbotOptions,
ChatMessage,
ChatbotConfig,
ChatSession,
} from '@docimal/chatbot';
// Type-safe config object
const chatbotConfig: ChatbotEmbedProps = {
apiKey: 'dcml_pk_YOUR_API_KEY',
apiBaseUrl: 'https://api.docimal.site/agents',
user: {
id: 'user_123',
email: 'user@example.com',
name: 'John Doe',
customAttributes: { plan: 'pro', company: 'Acme' },
},
options: {
position: 'bottom-right',
startOpen: false,
persistSession: true,
},
theme: {
mode: 'light',
primaryColor: '#6366f1',
headerStyle: 'colored',
},
onMessage: (msg: ChatMessage) => {
console.log(`[${msg.role}] ${msg.content}`);
},
};Type Description ChatbotEmbedPropsFull props type for the DocimalChatbot component ChatbotThemeType for the theme prop ChatbotOptionsType for the options prop ChatMessageIndividual message object (role, content, sources, components) ChatbotConfigRemote config fetched from the API (name, avatar, features) ChatSessionChat session object (id, chatbotId, status) RichMessageComponentUnion type for all 15 rich component types
Best Practices Render once, high in the tree Environment variable for the API key useChatbot() requires DocimalChatbot in the same tree Iframe vs. React component — when to use each