> ## Documentation Index
> Fetch the complete documentation index at: https://docs.illumichat.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Widget in React & Next.js

> Add the IllumiChat widget to your React or Next.js application

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:

```tsx theme={null}
// 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:

```tsx theme={null}
// 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>
  );
}
```

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

## Configurable Component

Create a reusable component that accepts configuration props:

```tsx theme={null}
// components/IllumiChatWidget.tsx
'use client';

import Script from 'next/script';

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

export function IllumiChatWidget({
  assistantId,
  primaryColor,
  position = 'bottom-right',
  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-auth-mode={authMode}
      strategy="lazyOnload"
    />
  );
}
```

Usage:

```tsx theme={null}
<IllumiChatWidget
  assistantId="your-assistant-id"
  primaryColor="#0066FF"
/>
```

## Programmatic Control

Use the global `IllumiChat` API to control the widget from your React components:

```tsx theme={null}
'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:

```typescript theme={null}
// 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:

```tsx theme={null}
'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:

```tsx theme={null}
'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:

```tsx theme={null}
'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:

```tsx theme={null}
'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-visitor-id={session?.user?.id}
      strategy="lazyOnload"
    />
  );
}
```

<Warning>
  Avoid passing sensitive user data through data attributes. The widget is client-side JavaScript and data attributes are visible in the DOM.
</Warning>

## Plain React (non-Next.js)

For React apps without Next.js, load the script manually:

```tsx theme={null}
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:

```tsx theme={null}
// 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"
    />
  );
}
```

```bash theme={null}
# .env.local
NEXT_PUBLIC_ILLUMICHAT_ASSISTANT_ID=your-dev-assistant-id

# .env.production
NEXT_PUBLIC_ILLUMICHAT_ASSISTANT_ID=your-prod-assistant-id
```

<Tip>
  See the full [Widget SDK Reference](/widget/sdk-reference) for all available methods, events, and configuration options.
</Tip>
