---
title: Widget SDK
description: The Widget SDK allows developers to easily initialize and configure ChatBotKit AI Widgets. This guide provides detailed instructions for embedding, utilizing the global object, and managing widget properties and events.
tags:
  - widget
  - SDK
category: Developers
---
The ChatBotKit Widget SDK enables the initialization and configuration of ChatBotKit AI Widgets, allowing for either automatic or manual setup.

## Embedding (v2)

The fastest method to install and display a ChatBotKit AI Widget is to incorporate the Widget SDK script and provide configuration parameters using data properties. For instance:

`````html
<!-- embed the widget sdk and instantiate the widget -->
<script src="https://static.chatbotkit.com/integrations/widget/v2.js" data-widget="{WIDGET_ID}"></script>
`````

Additional widget properties, which are detailed below, can also be specified as data attributes. For example:

`````html
<!-- embed the widget sdk and instantiate the widget with additional properties -->
<script src="https://static.chatbotkit.com/integrations/widget/v2.js" data-widget="{WIDGET_ID}" data-open="true"></script>
`````

If the `data-widget` property is absent, the SDK will initialize but not instantiate any widget. In this scenario, you must instantiate the widget using a custom HTML tag. For example:

`````html
<!-- embed the widget sdk -->
<script src="https://static.chatbotkit.com/integrations/widget/v2.js"></script>
<!-- instantiate a widget somewhere inside your application -->
<chatbotkit-widget widget="{WIDGET_ID}" open="true"/>
`````

### Data Attributes

All widget properties can be set as `data-*` attributes on the script tag or as attributes on the `<chatbotkit-widget>` element. Below is the full list of supported attributes:

| Attribute | Default | Description |
| --- | --- | --- |
| `widget` | - | The widget ID (required for automatic instantiation) |
| `open` | `false` | Whether the widget starts open |
| `cache` | `true` | Cache the conversation across page navigations |
| `session` | - | An explicit session ID to use |
| `layout` | `default` | Layout mode |
| `position` | `bottom-right` | Screen position: `bottom-right`, `bottom-left`, `top-right`, `top-left`, or `fullscreen` |
| `placeholder` | - | Placeholder text for the message input |
| `language` | - | Language code for the widget UI |
| `baricon` | - | Custom icon URL for the bar |
| `bartitle` | - | Custom title text for the bar |
| `boticon` | - | Custom icon URL for bot messages |
| `usericon` | - | Custom icon URL for user messages |
| `buttonicon` | - | Custom icon URL for the toggle button |
| `hidebar` | `false` | Hide the message bar |
| `hidebutton` | `false` | Hide the toggle button |
| `plugins` | - | Comma-separated list of plugin names |
| `host` | - | Override the host portion of the widget frame URL (useful for self-hosted deployments) |

For example, to position the widget in the bottom-left corner with a custom placeholder:

`````html
<script
  src="https://static.chatbotkit.com/integrations/widget/v2.js"
  data-widget="{WIDGET_ID}"
  data-position="bottom-left"
  data-placeholder="Ask me anything..."
></script>
`````

The same attributes work on the custom element:

`````html
<chatbotkit-widget widget="{WIDGET_ID}" position="bottom-left" placeholder="Ask me anything..."/>
`````

## ChatBotKit Global Object (v2)

The ChatBotKit Global Object is a JavaScript variable available globally, created immediately upon execution of the widget script. It provides quick access to the widget instance created through automatic initialization, rather than through the `chatbotkit-widget` custom HTML tag.

### Properties

- `instance: ChatBotKitWidget|null`  - Returns the current widget instance. If the widget is not yet ready, this property will return `null` instead.
- `instancePromise: Promise<ChatBotKitWidget>` - Returns a promise that resolves to the widget instance. This property allows for convenient use of `await` to access the instance once it becomes available. It is particularly useful for performing initialization or other tasks on the widget as soon as it is made available.

### Window Properties

- `chatbotkitWidgetConfiguration: object` - This global variable can be used to add or override existing configuration properties, including the widget ID and other properties discussed in this document. It accepts a `params` key for widget attributes and a `style` key for custom CSS overrides.

`````javascript
window.chatbotkitWidgetConfiguration = {
  params: {
    widget: '{WIDGET_ID}',
    position: 'bottom-left',
    placeholder: 'Ask me anything...',
  },
  style: {
    widget: {
      bottom: '20px',
      right: '20px',
    },
  },
}
`````

### Window Events

- `chatbotkitWidgetInit, (event: { target: ChatBotKitWidget })`  - The event is dispatched to the window once the SDK is initialized and the widget becomes available. This method is particularly useful for performing initialization or other tasks on the widget as soon as it is ready.

### Window Functions

- `chatbotkitWidgetInit(instance: ChatBotKitWidget) -> void`  - This is a global function that, if present, will be called when the widget is initialized and available.

## ChatBotKit Widget (v2)

The ChatBotKit Widget is a custom HTML element that functions like standard HTML elements, but it also includes additional helper methods and properties for interacting with the AI widget.

### Properties

- `ready: boolean` (read-only) - Indicates whether the widget is ready for interaction.
- `readyPromise: Promise<boolean>` (read-only) - A promise that resolves when the widget is ready. Useful for awaiting widget readiness before performing operations.
- `messages: Message[] | null` - An array of messages currently displayed inside the widget. You can update this array by assigning a new value to this property. Note that modifying the array of messages does not equate to sending a message from the user. Only messages sent by the user are accepted as part of the conversation when it is created.
- `notifications: Record<string, NotificationDefinition | null>` - An object containing notifications to be displayed alongside the conversation. Notifications will appear in the message peek when the widget is closed, and also if they have not yet been seen.
- `functions: Record<string, FunctionDefinition | null> | null` - An object containing function definitions available to the AI bot. You can modify these functions by directly assigning new values to this property.
- `contact: Contact | null` - Contact information associated with the widget session.
- `meta: Record<string, unknown> | null` - Any meta information that will be included when the conversation is created.
- `open: boolean` - A property that can be used to verify or ensure that the widget is open.
- `widget: string` - The ID of the widget to be used for this instance.
- `placeholder: string | null` - Placeholder text shown in the message input field.
- `language: string | null` - Language code used for the widget UI (e.g. `en`, `de`, `fr`).
- `host: string | null` - Overrides the host portion of the widget frame URL. Useful for self-hosted or custom deployments.

### Methods

- `hide() -> void` - Hides the widget by changing its visibility. Does not toggle the open state.
- `show() -> void` - Shows the widget by changing its visibility. Does not toggle the open state.
- `restartConversation() -> void` - Restarts the current conversation. Clears all messages and resets the conversation session.
- `initiateMessage(props: InitiateMessageOptions) -> void` - Initiates a new message. The optional `text` property pre-fills the message input.
- `sendMessage(props: SendMessageOptions) -> void` - Sends a message on behalf of the end-user. Set `hidden` to `true` to hide the message from the conversation UI. Set `respond` to `true` to trigger a bot response.
- `maximize() -> void` - Maximizes the widget to take up more screen space.
- `minimize() -> void` - Minimizes the widget back to its default size.
- `render(props: RenderOptions) -> void` - Renders custom content inside the widget.
- `registerFunctions(functions: Record<string, FunctionDefinition | null>) -> void` - Registers additional functions with the widget. Functions are merged with any existing registrations.
- `unregisterFunctions(functions: string[]) -> void` - Unregisters functions by their names.
- `assignContact(props: Contact) -> void` - Assigns contact information to the widget session. This is a legacy method; prefer setting the `contact` property directly.

### Events

- `connect, (event: { target: ChatBotKitWidget })` - Triggered when the widget element is added to the DOM.
- `ready, (event: { target: ChatBotKitWidget })` - Triggered when the widget is ready for interaction.
- `send, (event: { target: ChatBotKitWidget, data: Message })` - Triggered when a message is sent by the end-user or through the `sendMessage` method.
- `receive, (event: { target: ChatBotKitWidget, data: Message })` - Triggered when a message is received from the bot.
- `item, (event: { target: ChatBotKitWidget, data: object })` - Triggered for each conversation item processed by the widget (e.g. when a function call result is returned). Useful for monitoring the full conversation flow at a low level.
- `disconnect, (event: { target: ChatBotKitWidget })` - Triggered when the widget element is removed from the DOM.

## Using the SDK Packages

The widget works out of the box with just the embedded script tag, but for more advanced use-cases two companion npm packages are available. The `@chatbotkit/widget` package provides TypeScript type definitions for the widget custom element, and the `@chatbotkit/react` package provides React hooks for interacting with widget instances. You can use either or both depending on your stack.

### @chatbotkit/widget - TypeScript Types

The `@chatbotkit/widget` package gives you type-safe access to every property, method, and event described above. This is useful when working with the widget directly in a TypeScript project.

#### Installation

`````bash
npm install @chatbotkit/widget
`````

#### Importing Types

`````typescript
import type {
  ChatBotKitWidgetElementV2,
  ChatBotKitGlobalObject,
  Message,
  FunctionDefinition,
  Contact,
  Meta,
  NotificationDefinition,
  SendMessageOptions,
  InitiateMessageOptions,
  RenderOptions,
} from '@chatbotkit/widget/v2'
`````

#### Type Reference

| Type | Description |
| --- | --- |
| `ChatBotKitWidgetElementV2` | The widget custom element interface extending `HTMLElement` |
| `ChatBotKitGlobalObject` | The `window.chatbotkitWidget` global object |
| `Message` | A conversation message: `{id, type, text, meta?}` |
| `FunctionDefinition` | A function registration: `{description, parameters, handler}` |
| `Contact` | Contact information: `{name?, email?, phone?}` |
| `Meta` | Alias for `Record<string, unknown>` |
| `NotificationDefinition` | A notification: `{text}` |
| `SendMessageOptions` | Options for `sendMessage`: `{text, hidden?, respond?}` |
| `InitiateMessageOptions` | Options for `initiateMessage`: `{text?}` |
| `RenderOptions` | Options for `render`: indexed object |

#### Global Augmentations

The package augments the global `Window` interface and `HTMLElementTagNameMap`. This means `document.querySelector('chatbotkit-widget')` returns a properly typed `ChatBotKitWidgetElementV2` element and `window.chatbotkitWidget` is typed as `ChatBotKitGlobalObject` - no manual casting required.

`````typescript
// accessing the global object is fully typed
const instance = await window.chatbotkitWidget.instancePromise

// querying the DOM returns the correct type
const widget = document.querySelector('chatbotkit-widget')
if (widget) {
  widget.open = true
}
`````

### @chatbotkit/react - React Hooks

The `@chatbotkit/react` package provides React hooks that wrap the widget instance lifecycle for you. The hooks handle waiting for the widget to be ready, managing state updates, and cleaning up on unmount.

#### Installation

`````bash
npm install @chatbotkit/react
`````

#### useWidgetInstance

Returns the widget instance once it is ready. Accepts an optional CSS selector as the first argument to target a specific widget element, and an optional `deps` array as the second argument to re-run the DOM query when specific values change.

`````javascript
import { useWidgetInstance } from '@chatbotkit/react/hooks/useWidgetInstance'

function MyComponent() {
  const instance = useWidgetInstance()

  if (!instance) {
    return null // widget not ready yet
  }

  return (
    <button onClick={() => instance.open = !instance.open}>
      Toggle Widget
    </button>
  )
}
`````

You can also pass a selector to target a specific widget element when multiple widgets are on the page:

`````javascript
const instance = useWidgetInstance('chatbotkit-widget#my-widget')
`````

#### useWidgetInstanceFunctions

Sets the active functions on the widget instance. The functions are applied whenever the instance becomes available or the `functions` value changes. The entire set of functions is replaced on each update, so pass the complete set of functions you want registered.

Accepts an options object as the first argument with:

- `functions` - An object mapping function names to `FunctionDefinition` objects (or `null` to remove a function)
- `selector` - Optional CSS selector to target a specific widget element (defaults to the first `chatbotkit-widget` element)

An optional `deps` array can be passed as the second argument to control when the DOM query for the widget element re-runs.

`````javascript
import { useWidgetInstanceFunctions } from '@chatbotkit/react/hooks/useWidgetInstanceFunctions'

function MyComponent() {
  const instance = useWidgetInstanceFunctions({
    functions: {
      getWeather: {
        description: 'Get the current weather for a location',
        parameters: {
          type: 'object',
          properties: {
            location: { type: 'string', description: 'City name' },
          },
          required: ['location'],
        },
        handler: async ({ location }) => {
          const res = await fetch(`/api/weather?city=${encodeURIComponent(location)}`)
          return res.json()
        },
      },
    },
  })

  return null
}
`````

When multiple widgets are on the page, use `selector` to target a specific one:

`````javascript
const instance = useWidgetInstanceFunctions({
  selector: 'chatbotkit-widget#support-widget',
  functions: { ... },
})
`````

#### useWidgetInstanceNotifications

Sets the active notifications on the widget instance. Notifications are applied whenever the instance becomes available or the `notifications` value changes.

Accepts an options object as the first argument with:

- `notifications` - An object mapping notification IDs to `NotificationDefinition` objects (or `null` to remove a notification)
- `selector` - Optional CSS selector to target a specific widget element (defaults to the first `chatbotkit-widget` element)

An optional `deps` array can be passed as the second argument to control when the DOM query for the widget element re-runs.

`````javascript
import { useWidgetInstanceNotifications } from '@chatbotkit/react/hooks/useWidgetInstanceNotifications'

function MyComponent() {
  const instance = useWidgetInstanceNotifications({
    notifications: {
      welcome: { text: 'Welcome! How can I help you today?' },
    },
  })

  return null
}
`````

When multiple widgets are on the page, use `selector` to target a specific one:

`````javascript
const instance = useWidgetInstanceNotifications({
  selector: 'chatbotkit-widget#support-widget',
  notifications: { ... },
})
`````

## Debugging

The widget supports debug flags that can be set on the `window` object before the widget script loads. These enable console logging for troubleshooting.

`````javascript
// enable warning logs
window.CHATBOTKIT_LOG_WARNING = true  // or: window.CHATBOTKIT_WARNING_LOG = true

// enable error logs
window.CHATBOTKIT_LOG_ERROR = true    // or: window.CHATBOTKIT_ERROR_LOG = true

// enable debug logs (verbose)
window.CHATBOTKIT_LOG_DEBUG = true    // or: window.CHATBOTKIT_DEBUG_LOG = true
`````

| Flag | Alias | Output | Description |
| --- | --- | --- | --- |
| `CHATBOTKIT_LOG_WARNING` | `CHATBOTKIT_WARNING_LOG` | `console.warn` | Widget warnings (e.g. setting properties before ready) |
| `CHATBOTKIT_LOG_ERROR` | `CHATBOTKIT_ERROR_LOG` | `console.error` | Explicit error log entries (in addition to unhandled errors) |
| `CHATBOTKIT_LOG_DEBUG` | `CHATBOTKIT_DEBUG_LOG` | `console.log` | Verbose internal debug events |

All messages are prefixed with `[ChatBotKit Widget]`. Errors are always written to `console.error` regardless of these flags.

## Session Persistence

By default the widget saves its `open` state to `sessionStorage` under the key `chatbotkit-widget-open`. When the page is reloaded within the same browser session, the widget restores the previous open/closed state after a short delay. This means a user who had the widget open will see it reopen automatically on navigation.

If you need to override this behavior, set the `open` property explicitly after the widget is ready:

`````javascript
const instance = await window.chatbotkitWidget.instancePromise
instance.open = false // always start closed
`````

## Tips & Tricks

### Creating a widget instance manually

You can manually create a widget instance by first including the Widget SDK and then adding the widget element anywhere within the body of your page.

Here’s how to do it:

`````javascript
<html>
  <head>
    <!-- embed the widget sdk -->
    <script src="https://static.chatbotkit.com/integrations/widget/v2.js"></script>
  </head>
  <body>
    <!-- instantiate a widget somewhere inside your application -->
    <chatbotkit-widget widget="{WIDGET_ID}"/>
  </body>
</html>
`````

### Assigning notifications

The ChatBotKit Widget can display various types of interactive messages and notifications, which can be dynamically inserted. The widget automatically manages the notification state. Removing a notification from the notifications object will also remove it from the conversation. New notifications will appear in the order they were added to the notifications object.

Consider the following example:

`````javascript
// a placeholder function to retrieve the available notifications from the applicaion
  
async function getNotifications() {
  // artificial delay to simulate network fetch
    
  await new Promise((resolve) => {
    setTimeout(() => resolve(), 1000)
  })

  // return available notifications
  
  const uniqueNotificationId = Math.random().toString(32).slice(2)
    
  return {
    [uniqueNotificationId]: {
      text: 'Hi Sara, your device has been offline for 12 hours\n\n[What is the current status of my device]() [How can I get my device back online]()'
    }
  }
}

// a helper function to setup the notifications
  
async function setupNotifications() {
  const notifications = await getNotifications()

  const instance = await window.chatbotkitWidget.instancePromise

  instance.notifications = notifications
}

setupNotifications()
`````

In the example above, we retrieve a list of notifications to present to the user and assign them to the widget once it becomes available via the `instancePromise` property.

This example will create an effect similar to the one shown in the video below.

### Sending messages

You can send messages on behalf of the end-user programmatically. The `sendMessage` method accepts an options object with `text`, and optional `hidden` and `respond` flags.

`````javascript
const instance = await window.chatbotkitWidget.instancePromise

// send a visible message (same as the user typing it)
instance.sendMessage({ text: 'Hello!' })
`````

To send a hidden message that triggers a bot response without showing anything in the UI, set `hidden` to `true` and `respond` to `true`. This is useful for sending context or instructions to the bot behind the scenes:

`````javascript
const instance = await window.chatbotkitWidget.instancePromise

// send context silently and trigger a bot response
instance.sendMessage({
  text: 'The user just landed on the pricing page',
  hidden: true,
  respond: true,
})
`````

You can also listen for outgoing and incoming messages using the `send` and `receive` events:

`````javascript
const instance = await window.chatbotkitWidget.instancePromise

instance.addEventListener('send', (event) => {
  console.log('User sent:', event.data.text)
})

instance.addEventListener('receive', (event) => {
  console.log('Bot replied:', event.data.text)
})
`````

### Pre-filling the message input

Use `initiateMessage` to pre-fill the message input without sending it. This is handy for suggested prompts or onboarding flows:

`````javascript
const instance = await window.chatbotkitWidget.instancePromise

instance.open = true
instance.initiateMessage({ text: 'How do I get started?' })
`````
