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

# Widget JavaScript SDK

> Add the widget from JavaScript — pass values from your page, open and close the chat, and react to events such as answer_generated.

The regular [install snippet](/conversation-flows/channels/widget#3-install-on-your-site) is enough for most sites. Use the JavaScript SDK when your page needs to talk to the widget:

* pass values the page already knows, for example from your app's state;
* open or close the chat from your own buttons;
* show the conversation inside your own element instead of the floating bubble;
* react when the agent answers — for example to log it, or to show the answer in your own interface.

Snippets you already installed keep working; the SDK is an addition, not a replacement.

## Add the widget

In the widget channel, click **Install Widget** and open the **JavaScript** tab. It looks like this:

```html theme={null}
<script>window.CogniAgent=window.CogniAgent||function(){(CogniAgent.q=CogniAgent.q||[]).push(arguments)};</script>
<script async src="https://embed.cogniagent.ai/embed.js"></script>
<script>
  CogniAgent('createWidget', {
    flowId: 'YOUR_FLOW_ID',
    channelId: 'YOUR_CHANNEL_ID',
    parameters: { order_id: 'A-1001', plan: 'pro' },
    on: {
      answer_generated: function (event) {
        console.log('The agent answered:', event.text);
      },
    },
  });
</script>
```

The first line makes `CogniAgent(...)` safe to call before `embed.js` has loaded: calls are queued and run in order once it loads. After loading, `CogniAgent.createWidget(options)` also works and returns a handle to control the widget.

<Warning>
  `parameters` are part of your page, so visitors can see and change them — the same rules as [values in the embed code](/conversation-flows/channels/widget-parameters). For values visitors can't change, create a [widget link](/conversation-flows/channels/widget-links) on your server and pass its code as `launchToken`.
</Warning>

## Options

| Option | What it does |
| - | - |
| `flowId`, `channelId` | Which agent and widget channel to open. |
| `launchToken` | Open a [widget link](/conversation-flows/channels/widget-links) instead — the code your server got from the [Widget Launch API](/api/widget-launches). Replaces `flowId`/`channelId`. |
| `parameters` | Values for the agent's [Initial Parameters](/conversation-flows/build/flow-settings#initial-parameters). |
| `parametersFromUrl` | Read these parameters from the page address too: a list of names, or `true` for all of the agent's parameters. See [Values from the page address](#values-from-the-page-address). |
| `target` | A CSS selector or element to show the chat in. Without it, the widget shows its usual floating bubble. |
| `open` | `true` to start with the chat open. |
| `apiUrl` | Only when the install snippet you copied sets `data-api-url`; use the same value. |
| `on` | Event listeners, for example `{ answer_generated: fn }`. |

## Control the widget

```js theme={null}
const widget = CogniAgent.createWidget({ flowId: '…', channelId: '…' });

widget.open();
widget.close();
widget.setParameters({ order_id: 'A-1002' }); // only right after createWidget, before it connects
widget.restart({ parameters: { order_id: 'A-1003' } }); // forget this conversation, start a new one
const stop = widget.on('answer_generated', (event) => { /* … */ });
stop(); // remove the listener
widget.destroy(); // remove the widget from the page
```

Values are fixed as soon as the widget connects, which happens right after `createWidget`. Pass your values in `createWidget`; `setParameters` only works in the same moment you create the widget, and afterwards does nothing (the browser console says so). Use `restart` to begin a new conversation with new values. A widget opened from a widget link can't be restarted — its values belong to the link.

A widget shown in your own element (`target`) is always open, so `open` and `close` don't apply to it.

You can add several widgets to one page — each keeps its own conversation (two widgets for the same agent and channel share one). Floating widgets all sit in the same corner, so show at most one floating widget and put the others in your own elements.

## Events

| Event | When | Details |
| - | - | - |
| `ready` | The widget has loaded | — |
| `session_started` | A conversation started or resumed | `sessionId` |
| `message` | A message was shown, from the visitor or the agent | `role` (`user` or `assistant`), `text`, `timestamp` |
| `answer_generated` | The agent finished an answer | `sessionId`, `text` (the full answer), `timestamp` |
| `conversation_ended` | The widget learns the conversation has ended — for example when a widget link is reopened after its conversation ended | `sessionId` |
| `error` | Something went wrong | `code`, `message` |

`answer_generated` fires **once per answer**, with the complete text, after the agent has finished it — never for partial text while it's still being written. For spoken replies, `text` is the final text of the reply. Use it when your page needs the agent's answer, for example to show it in your own chat interface or to record it in your system.

An error in your listener doesn't break the widget; it's reported in the browser console.

## Values from the page address

On the **hosted page** (the test page and [widget links](/conversation-flows/channels/widget-links)), values can be put in the address:

* `#vars=` followed by the values as JSON, base64url-encoded: `#vars=eyJvcmRlcl9pZCI6IkEtMTAwMSJ9`
* or one value at a time: `#var_order_id=A-1001`

When both are present, `var_` wins for its name. Values after `#` stay in the browser — they're not sent to any server when the page loads.

On **your own pages**, the widget only reads the address when you say so — with the SDK option `parametersFromUrl: ['order_id']`, or with `data-parameters-from-url="order_id"` on the regular snippet (`"*"` for all of the agent's parameters). Only the names you list are read. Values written in your code win over values from the address.

Values from the address are shown as **Page URL** in the conversation's Parameters block and, like all values from the page, can be changed by visitors.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.