# Website widget (widget.js)

One script tag puts Texa AI's chat on your website. Every attribute, the JavaScript API and its events.


```html
<script src="https://api.texadesk.com/widget.js" async
        data-site-key="pk_live_..."
        data-session-url="/texa/session"
        data-title="Help" data-color="#144AA7" data-voice="true"></script>
```

The widget has no dependencies and lives in its own shadow DOM, so your styles never reach it. It
never holds a key. The full walkthrough is [Texa AI in your website and app](/guides/website-and-app).

This is **Texa AI's** chat. For Texa Desk's **live chat** (answered by your team, with Texa AI if you
switch it on), see [live chat](/desk/live-chat).

## Attributes

| Attribute | What |
|---|---|
| `data-site-key` | your site key (Texa AI → Developers → Website and app), for visitors who haven't signed in |
| `data-session-url` | a route on **your** server: `POST` answers a [widget session](/api-reference/texa-api/widgets/a-widget-session-for-one-customer-its-token-is-for-a-web-page-or-an-app) when someone is signed in, `401` when not |
| `data-title` | the chat's title |
| `data-greeting` | the first line visitors see |
| `data-color` | your colour for the button and the customer's messages |
| `data-voice` | `true` adds a **Talk** button: a voice call in the browser |
| `data-files` | `false` hides the paper clip |

With only `data-session-url`, the chat is for signed-in customers only; with only `data-site-key`,
for visitors only.

## JavaScript

The script loads `async`: call these after the `texa:ready` event, or set
`window.TexaWidgetSettings = { handlers: {...}, onOpenPage: fn }` before it loads.

| Call | Does |
|---|---|
| `TexaWidget.open()`, `TexaWidget.close()` | opens or closes the chat |
| `TexaWidget.signedIn()` | after your own sign-in in a single-page app: the same chat carries on as the customer |
| `TexaWidget.signedOut()` | after sign-out: forgets the chat on this browser |
| `TexaWidget.on(action, fn)` | a screen action: `fn(inputs)` does it on the page and returns its results, within 30 seconds |
| `TexaWidget.onOpenPage(fn)` | `fn(url, page)` when Texa AI takes the customer to a page; by default the page loads |

```js
window.addEventListener("texa:ready", () => {
  TexaWidget.onOpenPage((url) => router.push(url));
  TexaWidget.on("fill_delivery_address", async ({ street, city }) => {
    form.street.value = street;
    form.city.value = city;
    return { filled: true };
  });
});
```

## Content security policy

If your site sends a CSP, allow `https://api.texadesk.com` in `script-src` and `connect-src`, and
`wss://voice.texadesk.com` in `connect-src` for voice.
