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/chatbot
ExportImport fromDescription
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.

tsx
// 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

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:

tsx
// 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.

tsx
// 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.

MethodDescription
open()Open the chat window and clear the unread count.
close()Close the chat window.

Open from a nav button

tsx
// 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

tsx
// 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

tsx
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

tsx
// 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

PropTypeDefaultDescription
apiKeystringRequired. Your public API key from the dashboard.
apiBaseUrlstringhttps://api.docimal.site/agentsAPI endpoint. Override for self-hosted deployments.
chatbotIdstringSpecify if your workspace has multiple agents.

User Identity user

FieldTypeDescription
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

PropTypeDefaultDescription
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

PropTypeDescription
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

CallbackSignatureDescription
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

PropTypeDefaultDescription
apiKeystringRequired. Your public API key.
chatbotIdstringRequired. The chatbot ID to embed.
baseUrlstringhttps://api.docimal.siteBackend API base URL.
embedOriginstringhttps://app.docimal.siteOrigin of the embed page (for postMessage security).
primaryColorstringBrand color hex for the iframe widget.
widthstring | number400pxIframe width.
heightstring | number600pxIframe height.
classNamestringCSS class applied to the iframe element.
styleCSSPropertiesInline style applied to the iframe element.
onReady() => voidFired when the iframe widget is ready.
onMessage(msg: unknown) => voidFired on each message from the iframe.
onError(err: string) => voidFired on error events from the iframe.

TypeScript

All types are bundled with the package — no @types/ package needed.

tsx
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}`);
  },
};
TypeDescription
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

What's Next?