# Website Widget

> Get your Mojeeb agent's website chat widget and its embed code with GET /v1/agents/{agentId}/widget, for Mojeeb's floating chat button or a chat your own page opens.

Every agent has one website chat widget: the chat visitors open on your site, answered by the agent's AI. `GET /v1/agents/{agentId}/widget` returns it with the code to paste into a page, so a site builder, a CMS plugin or a deploy script can install the chat without anyone copying code from the dashboard. It also says whether the widget is on and how it looks. See [Website Widget](/docs/channels/website-widget) for how it works in the dashboard.

## How do I get the embed code?

```bash
curl https://api.mojeeb.app/v1/agents/YOUR_AGENT_ID/widget \
  -H "Authorization: Bearer mk_live_YOUR_KEY_HERE"
```

`embed_code` holds two versions of the code, `default` and `headless`. Paste one of them once per page, just before the closing `body` tag, exactly as returned. Fetch it from the API rather than writing your own: it may change, and the API always returns the current one. Every field is in the [Get an agent's website widget reference](../api-reference/get-widget).

## Which embed code should I use?

- **`default`** adds Mojeeb's floating chat button, with the widget's opening message in a bubble beside it. It's the dashboard's **Ready Made Widget**, and the right choice for most sites.
- **`headless`** adds no button: your page opens the chat from its own button or link. It's the dashboard's **Customized Integration**. The opening message doesn't show.

## How do I open the chat from my own button?

Paste the `headless` code, then open the chat with `MojeebWidget`. The widget creates `window.MojeebWidget` only after it has loaded its settings, a moment after the page itself, so wait for it before you use it:

```html
<button id="chat-button" type="button">Chat with us</button>

<!-- Paste the headless embed code from the API here -->

<script>
  var waitForMojeeb = setInterval(function () {
    if (window.MojeebWidget) {
      clearInterval(waitForMojeeb);
      MojeebWidget.attach('#chat-button');
    }
  }, 100);
</script>
```

`MojeebWidget.attach(selector)` makes every element that matches the CSS selector open the chat when clicked. You can also call `MojeebWidget.open()` yourself, or `MojeebWidget.open({ message: "Need help with your order?" })` to open the chat with an opening line of your own from the agent. `MojeebWidget.close()`, `MojeebWidget.toggle()` and `MojeebWidget.isOpen()` do what their names say. Both embed codes create the same `MojeebWidget`, so you can also open the default widget from your own links.

## Does reading the widget change anything?

Only the first time. An agent with no widget yet gets one when you first read it, set up with the dashboard's defaults and switched on, so the first call always returns code you can paste. After that, reading changes nothing. It's the same widget the dashboard shows, and its id never changes, so code you've pasted keeps working.

## Common questions

### Is the widget id a secret?

No. It's the `data-widget-id` in the embed code, so it's in the page source of every site that has the widget, and it only lets visitors chat with the agent. Your API key is the secret: never put it in a web page.

### Can I show the chat in a mobile app?

Yes, without the embed code. An app loads the chat page in a WebView with the widget's `id`, and needs no API key. See [Add the Chat to Your Mobile App](../mobile-apps) for the address, the messages the chat exchanges with the app, and a React Native component.

### Can I change the widget's colour or opening message through the API?

Not yet. Change them in the dashboard. The embed code stays the same, so pages that already have it show the change the next time they load.

### Can an agent have more than one widget?

No. Each agent has one widget. To put the same chat on several sites, paste the same embed code on each.

### Why is `MojeebWidget` undefined?

The widget hasn't finished loading its settings. Check for `window.MojeebWidget` every 100 milliseconds or so, and call it only once it exists: a `DOMContentLoaded` listener usually runs too early. Paste the embed code only once per page: a second copy starts a second widget, with its own chat button, and replaces `window.MojeebWidget`.

### What does `enabled: false` mean?

The widget is switched off: visitors can't start a chat or send messages, chats already open included, and the chat says it's unavailable. The dashboard has no switch for it today, so if your widget reads `false`, contact Mojeeb support.

### My site sends a Content-Security-Policy. What should I allow?

The widget's script comes from `chat.mojeeb.app`, its chat window from Mojeeb's CDN, its settings from Mojeeb's API and its font from Google Fonts, and it adds a style element to your page. Allow:

- `script-src`: `https://chat.mojeeb.app`. Older embed code loads the script from `https://mojeebcdn.z7.web.core.windows.net` instead: allow the address in your code's `src`.
- `frame-src`: `https://mojeebcdn.z7.web.core.windows.net`
- `connect-src`: `https://mojeebapi.azurewebsites.net`
- `style-src`: `'unsafe-inline'` and `https://fonts.googleapis.com`
- `font-src`: `https://fonts.gstatic.com`

If the chat still doesn't appear, open your browser's console: a blocked request names the address to allow, and a refused style names the `style-src` directive.

### Can I get the dashboard's installation link through the API?

No. The dashboard can share a link to installation instructions with your web developer. Through the API, send them the embed code instead.

### Which scope does it need?

`connections:read`, because the widget is one of the agent's channels. Every key holds it today; see [Authentication](../authentication).
