# Chat widget JavaScript API

> Every chat widget JavaScript command: init, identify, update, setTags, track, setContext, open, on and off, reset and destroy, with examples.

Your site controls the chat widget through one function, `HrcWidget`: tell it who the visitor is, open and close the window, listen to events. Every call looks like this: `HrcWidget('<command>', ...arguments)`.

## Loading and the queue

Use the [full embed code](https://hrc.lt/en/docs/widget/install). Calls made before the loader arrives wait in the `HrcWidget.q` queue and run in order, functions (callbacks) included. Calls made after the loader but before `init` are kept up to 100; over that a `track` is dropped first, never `identify`, `reset` or `on`.

A bad value or an unknown command never throws into your page: it is dropped with one console warning. `debug: true` tells you more.

## TypeScript types

The types with every command: [https://widget.hrc.lt/v1/hrc.d.ts](https://widget.hrc.lt/v1/hrc.d.ts). Download the file next to your code:

```ts
// Download into your project:
// https://widget.hrc.lt/v1/hrc.d.ts
/// <reference path="./hrc.d.ts" />

// checked by your editor
HrcWidget('open', { view: 'new', type: 'question' });
```

## init

Starts the widget. Calling `init` again with another key tears the old widget down and starts the new one.

```js
HrcWidget('init', {
  // from your embed code
  widgetKey: 'wk_xxxxxxxxxxxxxxxxxxxx',
  // or 'lt', 'en', 'ru', 'pl', ...
  locale: 'auto',
  // applied like update
  profile: { attributes: { plan: 'pro' } },
  context: {
    appVersion: '3.8.1',
    custom: { page_type: 'checkout' },
  },
  // 'hidden' for your own button
  launcher: 'default',
  zIndex: 2147483000,
  // true logs dropped values
  debug: false,
});
```

| Option      | Value                                                                 |
| ----------- | --------------------------------------------------------------------- |
| `widgetKey` | The widget key from the Install tab. Required.                        |
| `locale`    | `'auto'` or a language code such as `'lt'`.                           |
| `identity`  | The same as `identify`.                                               |
| `profile`   | The same as `update`, applied once the visitor has a session.         |
| `context`   | The same as `setContext`.                                             |
| `launcher`  | `'default'` or `'hidden'` (the button is hidden, `open` still works). |
| `zIndex`    | The widget's layer, 2147483000 by default.                            |
| `debug`     | `true` explains dropped values in the console.                        |

## identify

Recognizes a signed-in user: they see their conversations on any device. `userHash` is computed on your server, see [Identity verification](https://hrc.lt/en/docs/widget/identity-verification). You can pass profile fields with it.

```js
HrcWidget('identify', {
  // your user id, always a string
  externalId: String(user.id),
  email: user.email,
  name: user.name,
  // see "Identity verification"
  userHash: userHashFromYourServer,
  company: { id: 'acme-1', name: 'Acme', plan: 'Pro' },
  attributes: { plan: 'pro', seats: 12, trial_ends_at: '2026-12-01' },
  tags: ['vip'],
});
```

## update

A partial update of the visitor profile: name, phone, avatar, company and up to 50 custom fields. Fields merge one by one; `null` or `''` removes a field. Calls within 500 ms go out together. Rules and limits: [Visitor profile](https://hrc.lt/en/docs/widget/visitor-profile).

```js
HrcWidget('update', {
  phone: '+370 600 00000',
  company: {
    name: 'Acme',
    website: 'https://acme.example',
    plan: 'Pro',
  },
  // number, boolean, date or string
  attributes: {
    orders: 14,
    newsletter: true,
    signed_up_at: new Date('2024-03-12'),
    app_version: '3.8.1',
    // null or '' removes the key
    coupon: null,
  },
});
```

## setTags

An array adds tags, an object adds and removes them. Up to 20 tags per contact, letters, digits and hyphens.

```js
// adds these tags
HrcWidget('setTags', ['vip', 'beta']);
// adds and removes
HrcWidget('setTags', { add: ['churn-risk'], remove: ['beta'] });
```

## track

Records one thing the visitor did. Your team sees the newest 5 in the sidebar and all of them on the contact page.

```js
HrcWidget('track', 'plan-upgraded', { from: 'free', to: 'pro' });
HrcWidget('track', 'checkout.failed', {
  reason: 'card_declined',
  amount: 49.9,
});
```

## setContext

Replaces the session values sent with every next message. They are not stored on the profile. Up to 20 custom keys, values up to 200 characters.

```js
// Only for this visit's next messages
HrcWidget('setContext', {
  appVersion: '3.8.1',
  custom: { cart_id: 'c-1042', step: 'payment' },
});
```

## open, close, toggle and the launcher

`open` opens the window: `view` is `'home'`, `'new'` or `'list'`, `type` is `'bug'`, `'feature'` or `'question'`. With `view: 'new'`, the `message` option puts text in the new conversation's composer (not sent, up to 2000 characters).

```js
// the home view
HrcWidget('open');
// the visitor's conversations
HrcWidget('open', { view: 'list' });
// straight to the bug form
HrcWidget('open', { view: 'new', type: 'bug' });
// text in the composer, not sent
HrcWidget('open', { view: 'new', message: 'Order #1042: ' });
HrcWidget('close');
HrcWidget('toggle');
// open() still works
HrcWidget('hideLauncher');
HrcWidget('showLauncher');
```

## on and off: events

```js
function onUnread(event) {
  document.title = event.count ? '(' + event.count + ') Shop' : 'Shop';
}
// fires at once with the current count
HrcWidget('on', 'unread', onUnread);
HrcWidget('on', 'ready', function (event) {
  console.log(event.isIdentified, event.locale);
});
HrcWidget('on', 'conversation-started', function (event) {
  console.log(event.type);
});
// removes this callback
HrcWidget('off', 'unread', onUnread);
// removes every ready callback
HrcWidget('off', 'ready');
```

| Event                  | Payload                                                   | When                                                                                                           |
| ---------------------- | --------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| `ready`                | `{ isIdentified, hasConversations, unreadCount, locale }` | The widget started. An `on('ready')` added later gets the last value at once.                                  |
| `open`                 | `{ view }`                                                | Every open.                                                                                                    |
| `close`                | `{}`                                                      | Every close.                                                                                                   |
| `unread`               | `{ count }`                                               | At once with the current value, then on every change.                                                          |
| `message`              | `{ unreadCount }`                                         | A team reply arrived that the visitor has not read. No text, so other scripts on the page cannot read replies. |
| `conversation-started` | `{ conversationId, type }`                                | The visitor started a conversation.                                                                            |
| `identified`           | `{}`                                                      | `identify` succeeded.                                                                                          |
| `identify-failed`      | `{ code }`                                                | `identify` failed, for example `IDENTITY_INVALID`.                                                             |

A callback that throws logs one warning and never stops the widget or the other callbacks.

## setLocale, reset and destroy

```js
// switch the language now, or 'auto'
HrcWidget('setLocale', 'pl');
// on logout: forgets the visitor
HrcWidget('reset');
// removes the widget; call init again
HrcWidget('destroy');
```

`reset` forgets the session, the identity and every profile change, tag, event and session value not sent yet. Call it when the user signs out.

## Single page apps

The loader notices route changes (`pushState`, `popstate`) by itself, so messages carry the real page. React example: [Embed code, React and CSP](https://hrc.lt/en/docs/widget/install).
