Skip to main content
This guide covers how to integrate the IllumiChat widget into React and Next.js applications, including component patterns, TypeScript support, and programmatic control.

Basic Next.js Integration

The recommended approach for Next.js uses the next/script component:
// components/IllumiChatWidget.tsx
'use client';

import Script from 'next/script';

export function IllumiChatWidget() {
  return (
    <Script
      src="https://widget.illumichat.com/v1/widget.js"
      data-assistant-id="YOUR_ASSISTANT_ID"
      strategy="lazyOnload"
    />
  );
}
Add it to your root layout so it loads on every page:
// app/layout.tsx
import { IllumiChatWidget } from '@/components/IllumiChatWidget';

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <body>
        {children}
        <IllumiChatWidget />
      </body>
    </html>
  );
}
The 'use client' directive is required because next/script uses browser APIs. The widget itself is loaded asynchronously and will not affect your server-side rendering.

Configurable Component

Create a reusable component that accepts configuration props:
// components/IllumiChatWidget.tsx
'use client';

import Script from 'next/script';

interface IllumiChatWidgetProps {
  assistantId: string;
  primaryColor?: string;
  position?: 'bottom-right' | 'bottom-left';
  welcomeMessage?: string;
  authMode?: 'anonymous' | 'authenticated' | 'auto';
}

export function IllumiChatWidget({
  assistantId,
  primaryColor,
  position = 'bottom-right',
  welcomeMessage,
  authMode = 'anonymous',
}: IllumiChatWidgetProps) {
  return (
    <Script
      src="https://widget.illumichat.com/v1/widget.js"
      data-assistant-id={assistantId}
      data-primary-color={primaryColor}
      data-position={position}
      data-welcome-message={welcomeMessage}
      data-auth-mode={authMode}
      strategy="lazyOnload"
    />
  );
}
Usage:
<IllumiChatWidget
  assistantId="your-assistant-id"
  primaryColor="#0066FF"
  welcomeMessage="Hi! How can I help?"
/>

Programmatic Control

Use the global IllumiChat API to control the widget from your React components:
'use client';

export function SupportButton() {
  const openChat = () => {
    if (typeof window !== 'undefined' && window.IllumiChat) {
      window.IllumiChat.open();
    }
  };

  return (
    <button onClick={openChat}>
      Chat with Support
    </button>
  );
}

TypeScript Declarations

Add type declarations for the global API:
// types/illumichat.d.ts
interface IllumiChatAPI {
  open(): void;
  close(): void;
  toggle(): void;
  sendMessage(message: string): void;
  on(event: string, callback: (...args: any[]) => void): void;
  off(event: string, callback: (...args: any[]) => void): void;
}

declare global {
  interface Window {
    IllumiChat?: IllumiChatAPI;
  }
}

export {};

Event Handling

Listen to widget events using a custom hook:
'use client';

import { useEffect } from 'react';

export function useIllumiChatEvents() {
  useEffect(() => {
    const handleOpen = () => console.log('Widget opened');
    const handleClose = () => console.log('Widget closed');
    const handleMessage = (message: string) => {
      console.log('User sent:', message);
    };

    const interval = setInterval(() => {
      if (window.IllumiChat) {
        window.IllumiChat.on('open', handleOpen);
        window.IllumiChat.on('close', handleClose);
        window.IllumiChat.on('message:sent', handleMessage);
        clearInterval(interval);
      }
    }, 100);

    return () => {
      clearInterval(interval);
      if (window.IllumiChat) {
        window.IllumiChat.off('open', handleOpen);
        window.IllumiChat.off('close', handleClose);
        window.IllumiChat.off('message:sent', handleMessage);
      }
    };
  }, []);
}
Use it in your layout or page component:
'use client';

import { useIllumiChatEvents } from '@/hooks/useIllumiChatEvents';

export function WidgetEventListener() {
  useIllumiChatEvents();
  return null;
}

Conditional Loading

Load the widget only on specific pages or for specific users:
'use client';

import Script from 'next/script';
import { usePathname } from 'next/navigation';

export function IllumiChatWidget({
  assistantId,
}: {
  assistantId: string;
}) {
  const pathname = usePathname();

  // Only show on marketing and support pages
  const showWidget =
    pathname.startsWith('/support') ||
    pathname.startsWith('/pricing') ||
    pathname === '/';

  if (!showWidget) return null;

  return (
    <Script
      src="https://widget.illumichat.com/v1/widget.js"
      data-assistant-id={assistantId}
      strategy="lazyOnload"
    />
  );
}

Authenticated Widget

Pass user identity to the widget for authenticated conversations:
'use client';

import Script from 'next/script';
import { useSession } from 'next-auth/react'; // or your auth provider

export function IllumiChatWidget({
  assistantId,
}: {
  assistantId: string;
}) {
  const { data: session } = useSession();

  return (
    <Script
      src="https://widget.illumichat.com/v1/widget.js"
      data-assistant-id={assistantId}
      data-auth-mode={session ? 'authenticated' : 'anonymous'}
      data-user-name={session?.user?.name}
      data-user-email={session?.user?.email}
      strategy="lazyOnload"
    />
  );
}
Avoid passing sensitive user data through data attributes. The widget is client-side JavaScript and data attributes are visible in the DOM.

Plain React (non-Next.js)

For React apps without Next.js, load the script manually:
import { useEffect } from 'react';

export function IllumiChatWidget({
  assistantId,
}: {
  assistantId: string;
}) {
  useEffect(() => {
    if (document.getElementById('illumichat-widget')) return;

    const script = document.createElement('script');
    script.id = 'illumichat-widget';
    script.src = 'https://widget.illumichat.com/v1/widget.js';
    script.async = true;
    script.dataset.assistantId = assistantId;
    document.body.appendChild(script);

    return () => {
      const el = document.getElementById('illumichat-widget');
      if (el) el.remove();
    };
  }, [assistantId]);

  return null;
}

Environment-Based Configuration

Use environment variables to manage different assistants across environments:
// components/IllumiChatWidget.tsx
'use client';

import Script from 'next/script';

const ASSISTANT_ID = process.env.NEXT_PUBLIC_ILLUMICHAT_ASSISTANT_ID;

export function IllumiChatWidget() {
  if (!ASSISTANT_ID) return null;

  return (
    <Script
      src="https://widget.illumichat.com/v1/widget.js"
      data-assistant-id={ASSISTANT_ID}
      strategy="lazyOnload"
    />
  );
}
# .env.local
NEXT_PUBLIC_ILLUMICHAT_ASSISTANT_ID=your-dev-assistant-id

# .env.production
NEXT_PUBLIC_ILLUMICHAT_ASSISTANT_ID=your-prod-assistant-id
See the full Widget SDK Reference for all available methods, events, and configuration options.