npm package: @spilki/widget
Description: Embeddable Spilki assistant widget
Latest version: 1.0.35

# @spilki/widget

[![npm version](https://img.shields.io/npm/v/%40spilki/widget.svg)](https://www.npmjs.com/package/@spilki/widget)
[![bundle size](https://img.shields.io/badge/gzip%20%3C=35kB-success)](#size-budget)

Embeddable chat widget that connects your website visitors with the Spilki assistant backend via a secure Web Widget
channel.

## Features

- ✅ Zero runtime dependencies and <35 kB gzip UMD build
- ✅ Vanilla TypeScript UI with Shadow DOM isolation
- ✅ Automatic websocket with SSE / long-poll fallback
- ✅ JWT + origin validation handshake
- ✅ Local demo and mock backend for development

## Installation

```bash
pnpm add @spilki/widget
# or
npm install @spilki/widget
```

### CDN (UMD)

```html

<script src="https://cdn.jsdelivr.net/npm/@spilki/widget/dist/widget.umd.js"
        data-org="ori-bar"
        data-token="<your-jwt>"></script>
```

### ESM

```ts
import {initSpilkiWidget} from "@spilki/widget";

initSpilkiWidget({
    org: "ori-bar",
    token: "<your-jwt>"
});
```

## Options

| Option               | Type                              | Default                   | Description                                                                             |
|----------------------|-----------------------------------|---------------------------|-----------------------------------------------------------------------------------------|
| `org`                | `string`                          | –                         | Spilki organisation identifier.                                                         |
| `token`              | `string?`                         | –                         | Signed JWT obtained from the admin UI or backend.                                       |
| `apiBase`            | `string?`                         | `https://api.spilki.app`  | Override API endpoint (useful for staging/local).                                       |
| `position`           | `"bottom-right" \| "bottom-left"` | `"bottom-right"`          | Corner to anchor the bubble + panel.                                                    |
| `theme`              | `"auto" \| "light" \| "dark"`     | `"auto"`                  | Force light/dark or respect OS preference.                                              |
| `color`              | `string?`                         | `#6366f1`                 | Accent color for bubble + primary CTA.                                                  |
| `welcome`            | `string?`                         | "Hi! I'm your assistant." | Greeting shown when no conversation exists.                                             |
| `persist`            | `boolean?`                        | `true`                    | Persist session + history in localStorage.                                              |
| `allowedOriginsHint` | `string[]?`                       | –                         | List of origins expected to be in JWT allowlist. Logs warnings during misconfiguration. |
| `i18n`               | `Partial<WidgetI18n>?`            | –                         | Override UI strings (welcome, placeholder, sendLabel, typing, offline, title).          |
| `hooks`              | `Partial<WidgetHooks>?`           | –                         | Telemetry callbacks for open/close/message/error/transport change.                      |

## Security

The widget never stores credentials. Provide a short-lived JWT (HS256) issued server-side with the following claims:

```json
{
  "organisation_id": "ori-bar",
  "allowed_origins": [
    "https://yourdomain.com"
  ],
  "exp": 1760000000
}
```

During `POST /widget/session` the widget sends `Origin` and the JWT for verification. Expired tokens are rejected
client-side before any network call. Rotate tokens frequently and limit the allowed origins array to trusted domains
only.

See [`apps/mock-server/openapi.yaml`](../apps/mock-server/openapi.yaml) for the full handshake specification.

## Size budget

The `scripts/size-check.cjs` script ensures the UMD build stays below 35 kB gzip. CI runs the check prior to publish.

## Browser support

- Last two Chrome, Edge, Firefox versions
- Safari 15+

## Local development

```bash
pnpm install
pnpm -w dev # runs mock server + demo site
```

Open [http://localhost:5174](http://localhost:5174) and use **Issue token** to obtain a development JWT. Messages are
relayed via websocket by default; stop the websocket server to see SSE fallback.

## Publishing

The GitHub Actions workflow publishes on tags that match `v*`. Ensure `NPM_TOKEN` is configured in the repository
secrets before tagging `v0.1.4` or later.