@helpai/elements 1.7.0 → 1.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +34 -12
- package/configurator.mjs +1 -1
- package/docs/README.md +183 -0
- package/docs/analytics.md +551 -0
- package/docs/api-reference.md +622 -0
- package/docs/browser-support.md +302 -0
- package/docs/configuration.md +1001 -0
- package/docs/events-and-hooks.md +483 -0
- package/docs/faq.md +435 -0
- package/docs/frameworks.md +640 -0
- package/docs/installation.md +626 -0
- package/docs/options.md +323 -0
- package/docs/quickstart.md +229 -0
- package/docs/recipes.md +725 -0
- package/docs/security-privacy.md +575 -0
- package/docs/theming.md +570 -0
- package/docs/troubleshooting.md +523 -0
- package/elements-web-component.esm.js +39 -39
- package/elements-web-component.esm.js.map +4 -4
- package/elements.cjs.js +39 -39
- package/elements.cjs.js.map +4 -4
- package/elements.esm.js +39 -39
- package/elements.esm.js.map +4 -4
- package/elements.js +39 -39
- package/elements.js.map +4 -4
- package/index.d.ts +95 -8
- package/index.mjs +14 -14
- package/jsx-react.d.ts +15 -0
- package/jsx-svelte.d.ts +14 -0
- package/jsx-vue.d.ts +14 -0
- package/llms-full.txt +7862 -0
- package/llms.txt +36 -0
- package/loader.js +3 -3
- package/loader.min.js +1 -1
- package/package.json +36 -1
- package/react.d.ts +3552 -0
- package/react.mjs +62 -0
- package/schema.d.ts +56 -0
- package/schema.json +24 -2
- package/schema.mjs +1 -1
- package/web-component.d.ts +1561 -17
- package/web-component.mjs +13 -13
package/docs/options.md
ADDED
|
@@ -0,0 +1,323 @@
|
|
|
1
|
+
# Configuration — `ChatWidgetOptions`
|
|
2
|
+
|
|
3
|
+
The canonical surface lives in `src/schema/widget.ts` and
|
|
4
|
+
`src/schema/deployment.ts` as Zod schemas. Every field carries a
|
|
5
|
+
`.describe(...)` string and (where useful) `.meta({ examples })` —
|
|
6
|
+
this page is a flat reference auto-generated from those annotations.
|
|
7
|
+
|
|
8
|
+
When the schema and this doc disagree, **the schema wins**. Run
|
|
9
|
+
`bun run gen:docs` after editing a schema to refresh the tables; CI
|
|
10
|
+
fails if this file is out of sync.
|
|
11
|
+
|
|
12
|
+
For longer-form prose on what each subsystem does, see the
|
|
13
|
+
`features/` directory:
|
|
14
|
+
|
|
15
|
+
- Theming
|
|
16
|
+
- Sizing
|
|
17
|
+
- Launcher
|
|
18
|
+
- Header actions
|
|
19
|
+
- Composer
|
|
20
|
+
- Feedback
|
|
21
|
+
- i18n
|
|
22
|
+
- Modes
|
|
23
|
+
|
|
24
|
+
---
|
|
25
|
+
|
|
26
|
+
## Conventions
|
|
27
|
+
|
|
28
|
+
- Every field is optional unless its row says otherwise.
|
|
29
|
+
- "Default" is what the runtime applies when the field is absent.
|
|
30
|
+
`—` means there's no schema-level default; the resolver falls
|
|
31
|
+
through to runtime behaviour or leaves the field undefined.
|
|
32
|
+
- Field names use the schema (camelCase) form. The web-component +
|
|
33
|
+
`<script data-*>` boot accept the kebab-case equivalent (e.g.
|
|
34
|
+
`data-launcher-variant` ↔ `launcher.variant`).
|
|
35
|
+
- "Server-pushable" fields can arrive in `HandshakeResponse.config`;
|
|
36
|
+
see [§ Server settings](#server-settings).
|
|
37
|
+
|
|
38
|
+
---
|
|
39
|
+
|
|
40
|
+
<!-- AUTO-GENERATED:CONFIG-REFERENCE START -->
|
|
41
|
+
|
|
42
|
+
<!-- This block is generated by `scripts/gen-config-docs.ts` from the Zod
|
|
43
|
+
schemas in `src/schema/widget.ts` + `src/schema/deployment.ts`. Edit
|
|
44
|
+
those schemas (`.describe(...)` + `.meta({ examples })`) and run
|
|
45
|
+
`bun run gen:docs` to regenerate. CI fails when this block drifts. -->
|
|
46
|
+
|
|
47
|
+
### Connection (`ConnectionConfig`)
|
|
48
|
+
|
|
49
|
+
Where the widget talks to and how it authenticates. Owned by the embedding developer (typically baked into the page template / env var) — distinct from `userPrefs`, which is the dashboard-pushable UX surface.
|
|
50
|
+
|
|
51
|
+
| Field | Type | Default | Description |
|
|
52
|
+
| --------------------- | ----------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
53
|
+
| `widgetId` | `string` | `"default"` | Stable per-instance id used to namespace localStorage keys. Set this when mounting more than one widget on the same page so their conversation state doesn't collide. |
|
|
54
|
+
| `publicKey?` | `string` | — | Deployment public key (`agent_pk_…`) issued from the dashboard. Sent on every API call as the `x-public-key` header when present. |
|
|
55
|
+
| `aiAgentDeploymentId` | `string` | — | Required deployment UUID from the dashboard. Picks which agent / settings bundle answers this mount. Sent as `x-ai-agent-deployment-id`. |
|
|
56
|
+
| `baseUrl?` | `string` | — | MAIN site origin (e.g. `https://help.ai`) — the API modules derive from it: agent API at `${baseUrl}/api/agent`, data API at `${baseUrl}/api/data`. Set this to point at your staging / self-hosted / custom backend. Default: the brand's `defaultBaseUrl` baked at build time. |
|
|
57
|
+
| `agentApiBaseUrl?` | `string` | — | Full agent-API base — set it to reach a STANDALONE `module-agent-api` directly (local module on its own port, e.g. `http://localhost:3069`; routes attach as-is: `/pai/handshake`). Precedence: this option > derived from the main origin (`${baseUrl}/api/agent`). Not server-pushable. |
|
|
58
|
+
| `dataApiBaseUrl?` | `string` | — | Full data-API base (e.g. `https://help.ai/api/data`, or a standalone local module like `http://localhost:3071`) — the service serving content, form definitions (`GET /pai/bootstrap`), and form submissions at root-level paths. Precedence: this option > server-pushed `config.dataApiBaseUrl` > derived from the main origin (`${baseUrl}/api/data`). |
|
|
59
|
+
| `userContext?` | object | — | Host-asserted end-user context (informational, untrusted — not authentication). Recognised `id` / `email` / `name` / `plan` / `role` / `phone` plus any extra custom scalar fields forwarded to the agent. |
|
|
60
|
+
| `pageContext?` | object | — | Host-asserted page/visit context (informational, untrusted). Where the visitor is + the surface (`area`) they're using, plus any custom scalar fields, forwarded to the agent. |
|
|
61
|
+
| `endpoints?` | object | — | HTTP endpoint overrides. `upload` / `transcribe` paths are appended to the agent base (`${baseUrl}/api/agent`), `submitForm` to the data base (`dataApiBaseUrl`); absolute URLs are accepted too. |
|
|
62
|
+
| `debug?` | `boolean` \| `"off"` \| `"error"` \| `"warn"` \| `"info"` \| `"debug"` \| `"trace"` | — | Console log verbosity. `false` / `"off"` silences everything (default in production). `true` → `"debug"`. Levels `error` / `warn` / `info` / `debug` / `trace` gate output additively. Use `"trace"` to capture per-chunk SSE frames + every state transition. Also toggleable at runtime via `chat.setDebug(level)` or `?<brand>-debug=trace` in the page URL — the URL beats this option, this option beats the persisted `localStorage` value. |
|
|
63
|
+
|
|
64
|
+
**Examples:**
|
|
65
|
+
|
|
66
|
+
```json
|
|
67
|
+
[
|
|
68
|
+
{
|
|
69
|
+
"publicKey": "agent_pk_demo",
|
|
70
|
+
"aiAgentDeploymentId": "01900000-0000-7000-8000-000000000001"
|
|
71
|
+
},
|
|
72
|
+
{
|
|
73
|
+
"publicKey": "agent_pk_demo",
|
|
74
|
+
"aiAgentDeploymentId": "01900000-0000-7000-8000-000000000001",
|
|
75
|
+
"widgetId": "support"
|
|
76
|
+
},
|
|
77
|
+
{
|
|
78
|
+
"publicKey": "agent_pk_demo",
|
|
79
|
+
"aiAgentDeploymentId": "01900000-0000-7000-8000-000000000001",
|
|
80
|
+
"baseUrl": "https://api.acme.com"
|
|
81
|
+
}
|
|
82
|
+
]
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
---
|
|
86
|
+
|
|
87
|
+
### Deployment widget settings (`WidgetSettings`)
|
|
88
|
+
|
|
89
|
+
Portal-configurable widget settings — thirteen sections, one per dashboard tab. The backend pushes this shape on `/pai/handshake` under `config`, except `forms`, which the data API serves separately.
|
|
90
|
+
|
|
91
|
+
| Field | Type | Default | Description |
|
|
92
|
+
| --------------- | ------------------------------------------------------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
93
|
+
| `presentation?` | object | — | Layout fundamentals — mode, anchor corner, iframe isolation, panel size + drawer inset. |
|
|
94
|
+
| `behavior?` | object | — | Conversation behaviour — lifecycle, streaming, and the transcript surface (scroll, feedback). |
|
|
95
|
+
| `theme` | `"auto"` \| `"light"` \| `"dark"` \| `"host"` \| object | `"auto"` | Theme preference (`auto` follows OS) or a tokens override object (`accent`, `radius`, `fontFamily`). |
|
|
96
|
+
| `launcher?` | object | — | Floating-launcher (FAB) appearance and behaviour. The FAB is the round button in the corner that opens the chat panel. Floating mode only. |
|
|
97
|
+
| `header?` | object | — | Panel-header configuration. |
|
|
98
|
+
| `composer?` | object | — | Composer chrome — send-button styling + attachment limits. |
|
|
99
|
+
| `feedback?` | object | — | Audible + tactile feedback. |
|
|
100
|
+
| `i18n?` | object | — | Locale + i18n overrides. |
|
|
101
|
+
| `footer?` | object | — | Footer — attribution + composer disclaimer. |
|
|
102
|
+
| `features?` | object | — | Capability flags — file upload, voice mode, HITL, and operator requests. |
|
|
103
|
+
| `forms?` | object[] | — | Event-driven forms — an ordered list (order = priority). Each binds to trigger event(s), gates the chat until submit/skip, dedupes by frequency, and records via `endpoints.submitForm`. Generic across verticals. |
|
|
104
|
+
| `modules?` | object[] | — | Messenger tabs — an ordered list of up to 4 tabs, each picking a `layout` + the content collections it shows (`contentCollectionIds`) + a translatable `label`. One tab → no tab bar (just that content); zero → an empty state. Floating / drawer / modal only. |
|
|
105
|
+
| `tracking?` | object | — | Anonymous usage tracking for the widget owner — GA-style pixel events (open, send, form submit, …) with page / device / locale dimensions. Never includes message or form content; the only visitor identifier is the widget's anonymous visitorId. |
|
|
106
|
+
|
|
107
|
+
**Examples:**
|
|
108
|
+
|
|
109
|
+
```json
|
|
110
|
+
[
|
|
111
|
+
{
|
|
112
|
+
"presentation": {
|
|
113
|
+
"mode": "floating",
|
|
114
|
+
"position": "bottom-right"
|
|
115
|
+
},
|
|
116
|
+
"theme": "auto"
|
|
117
|
+
},
|
|
118
|
+
{
|
|
119
|
+
"presentation": {
|
|
120
|
+
"mode": "floating"
|
|
121
|
+
},
|
|
122
|
+
"theme": {
|
|
123
|
+
"accent": "#7c3aed",
|
|
124
|
+
"radius": "12px"
|
|
125
|
+
},
|
|
126
|
+
"launcher": {
|
|
127
|
+
"variant": "pill",
|
|
128
|
+
"label": "Ask AI",
|
|
129
|
+
"callout": {
|
|
130
|
+
"text": "👋 Need help?"
|
|
131
|
+
}
|
|
132
|
+
}
|
|
133
|
+
},
|
|
134
|
+
{
|
|
135
|
+
"presentation": {
|
|
136
|
+
"mode": "inline"
|
|
137
|
+
},
|
|
138
|
+
"behavior": {
|
|
139
|
+
"responseMode": "streaming"
|
|
140
|
+
},
|
|
141
|
+
"features": {
|
|
142
|
+
"voice": "local"
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
]
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
### Full widget config (`WidgetConfig`)
|
|
151
|
+
|
|
152
|
+
Full tooling config — connection (where + auth) + widget settings (look + behaviour) + page-mode handshake extras. The production widget does not import this Zod schema. Mode-specific constraints (e.g. `position` only meaningful in `floating`) are NOT enforced here so the same object can flow across mode changes.
|
|
153
|
+
|
|
154
|
+
| Field | Type | Default | Description |
|
|
155
|
+
| --------------------- | ----------------------------------------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
|
156
|
+
| `widgetId` | `string` | `"default"` | Stable per-instance id used to namespace localStorage keys. Set this when mounting more than one widget on the same page so their conversation state doesn't collide. |
|
|
157
|
+
| `publicKey?` | `string` | — | Deployment public key (`agent_pk_…`) issued from the dashboard. Sent on every API call as the `x-public-key` header when present. |
|
|
158
|
+
| `aiAgentDeploymentId` | `string` | — | Required deployment UUID from the dashboard. Picks which agent / settings bundle answers this mount. Sent as `x-ai-agent-deployment-id`. |
|
|
159
|
+
| `baseUrl?` | `string` | — | MAIN site origin (e.g. `https://help.ai`) — the API modules derive from it: agent API at `${baseUrl}/api/agent`, data API at `${baseUrl}/api/data`. Set this to point at your staging / self-hosted / custom backend. Default: the brand's `defaultBaseUrl` baked at build time. |
|
|
160
|
+
| `agentApiBaseUrl?` | `string` | — | Full agent-API base — set it to reach a STANDALONE `module-agent-api` directly (local module on its own port, e.g. `http://localhost:3069`; routes attach as-is: `/pai/handshake`). Precedence: this option > derived from the main origin (`${baseUrl}/api/agent`). Not server-pushable. |
|
|
161
|
+
| `dataApiBaseUrl?` | `string` | — | Full data-API base (e.g. `https://help.ai/api/data`, or a standalone local module like `http://localhost:3071`) — the service serving content, form definitions (`GET /pai/bootstrap`), and form submissions at root-level paths. Precedence: this option > server-pushed `config.dataApiBaseUrl` > derived from the main origin (`${baseUrl}/api/data`). |
|
|
162
|
+
| `userContext?` | object | — | Host-asserted end-user context (informational, untrusted — not authentication). Recognised `id` / `email` / `name` / `plan` / `role` / `phone` plus any extra custom scalar fields forwarded to the agent. |
|
|
163
|
+
| `pageContext?` | object | — | Host-asserted page/visit context (informational, untrusted). Where the visitor is + the surface (`area`) they're using, plus any custom scalar fields, forwarded to the agent. |
|
|
164
|
+
| `endpoints?` | object | — | HTTP endpoint overrides. `upload` / `transcribe` paths are appended to the agent base (`${baseUrl}/api/agent`), `submitForm` to the data base (`dataApiBaseUrl`); absolute URLs are accepted too. |
|
|
165
|
+
| `debug?` | `boolean` \| `"off"` \| `"error"` \| `"warn"` \| `"info"` \| `"debug"` \| `"trace"` | — | Console log verbosity. `false` / `"off"` silences everything (default in production). `true` → `"debug"`. Levels `error` / `warn` / `info` / `debug` / `trace` gate output additively. Use `"trace"` to capture per-chunk SSE frames + every state transition. Also toggleable at runtime via `chat.setDebug(level)` or `?<brand>-debug=trace` in the page URL — the URL beats this option, this option beats the persisted `localStorage` value. |
|
|
166
|
+
| `presentation?` | object | — | Layout fundamentals — mode, anchor corner, iframe isolation, panel size + drawer inset. |
|
|
167
|
+
| `behavior?` | object | — | Conversation behaviour — lifecycle, streaming, and the transcript surface (scroll, feedback). |
|
|
168
|
+
| `theme` | `"auto"` \| `"light"` \| `"dark"` \| `"host"` \| object | `"auto"` | Theme preference (`auto` follows OS) or a tokens override object (`accent`, `radius`, `fontFamily`). |
|
|
169
|
+
| `launcher?` | object | — | Floating-launcher (FAB) appearance and behaviour. The FAB is the round button in the corner that opens the chat panel. Floating mode only. |
|
|
170
|
+
| `header?` | object | — | Panel-header configuration. |
|
|
171
|
+
| `composer?` | object | — | Composer chrome — send-button styling + attachment limits. |
|
|
172
|
+
| `feedback?` | object | — | Audible + tactile feedback. |
|
|
173
|
+
| `i18n?` | object | — | Locale + i18n overrides. |
|
|
174
|
+
| `footer?` | object | — | Footer — attribution + composer disclaimer. |
|
|
175
|
+
| `features?` | object | — | Capability flags — file upload, voice mode, HITL, and operator requests. |
|
|
176
|
+
| `forms?` | object[] | — | Event-driven forms — an ordered list (order = priority). Each binds to trigger event(s), gates the chat until submit/skip, dedupes by frequency, and records via `endpoints.submitForm`. Generic across verticals. |
|
|
177
|
+
| `modules?` | object[] | — | Messenger tabs — an ordered list of up to 4 tabs, each picking a `layout` + the content collections it shows (`contentCollectionIds`) + a translatable `label`. One tab → no tab bar (just that content); zero → an empty state. Floating / drawer / modal only. |
|
|
178
|
+
| `tracking?` | object | — | Anonymous usage tracking for the widget owner — GA-style pixel events (open, send, form submit, …) with page / device / locale dimensions. Never includes message or form content; the only visitor identifier is the widget's anonymous visitorId. |
|
|
179
|
+
| `site?` | — | — | Site config — applies in `mode: "page"`. Comes from the handshake response, not user-edited. |
|
|
180
|
+
| `blocks?` | — | — | Blocks (nav + link cards) — applies in `mode: "page"`. Comes from the handshake response. |
|
|
181
|
+
|
|
182
|
+
**Examples:**
|
|
183
|
+
|
|
184
|
+
```json
|
|
185
|
+
[
|
|
186
|
+
{
|
|
187
|
+
"publicKey": "agent_pk_demo",
|
|
188
|
+
"aiAgentDeploymentId": "01900000-0000-7000-8000-000000000001",
|
|
189
|
+
"presentation": {
|
|
190
|
+
"mode": "floating"
|
|
191
|
+
},
|
|
192
|
+
"theme": "auto"
|
|
193
|
+
},
|
|
194
|
+
{
|
|
195
|
+
"publicKey": "agent_pk_demo",
|
|
196
|
+
"aiAgentDeploymentId": "01900000-0000-7000-8000-000000000001",
|
|
197
|
+
"presentation": {
|
|
198
|
+
"mode": "modal",
|
|
199
|
+
"size": {
|
|
200
|
+
"width": "720px",
|
|
201
|
+
"height": "640px"
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
]
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
---
|
|
209
|
+
|
|
210
|
+
### Handshake response (`HandshakeResponse`)
|
|
211
|
+
|
|
212
|
+
| Field | Type | Default | Description |
|
|
213
|
+
| ---------------- | -------- | ------- | ----------- |
|
|
214
|
+
| `deployment` | object | — | |
|
|
215
|
+
| `agent` | object | — | |
|
|
216
|
+
| `config?` | object | — | |
|
|
217
|
+
| `site?` | object | — | |
|
|
218
|
+
| `blocks?` | object | — | |
|
|
219
|
+
| `welcome?` | object | — | |
|
|
220
|
+
| `visitorId` | `string` | — | |
|
|
221
|
+
| `conversationId` | `string` | — | |
|
|
222
|
+
| `userPrefs?` | object | — | |
|
|
223
|
+
| `rebind?` | object | — | |
|
|
224
|
+
|
|
225
|
+
<!-- AUTO-GENERATED:CONFIG-REFERENCE END -->
|
|
226
|
+
|
|
227
|
+
---
|
|
228
|
+
|
|
229
|
+
## Storage
|
|
230
|
+
|
|
231
|
+
| Option | Type | Default | Server-push |
|
|
232
|
+
| --------- | --------------- | ----------------------- | ----------- |
|
|
233
|
+
| `storage` | `ClientStorage` | `LocalStorageAdapter()` | no |
|
|
234
|
+
|
|
235
|
+
```ts
|
|
236
|
+
interface ClientStorage {
|
|
237
|
+
get(key: string): string | null;
|
|
238
|
+
set(key: string, value: string): void;
|
|
239
|
+
remove(key: string): void;
|
|
240
|
+
}
|
|
241
|
+
```
|
|
242
|
+
|
|
243
|
+
Adapter methods are synchronous. Swap the default `localStorage` adapter for
|
|
244
|
+
`sessionStorage`, an encrypted wrapper, or an in-memory shim (tests, SSR). The
|
|
245
|
+
adapter receives dynamic `draft.<conversationId>` keys whose values are exact
|
|
246
|
+
unsent textarea text and owns their storage, retention, and privacy behavior.
|
|
247
|
+
|
|
248
|
+
`storage` and the function-typed `onMessage` / `onOpen` / `onClose` /
|
|
249
|
+
`onError` / `target` callbacks are runtime-only and not on the schema
|
|
250
|
+
(they can't be JSON-serialised).
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Callbacks
|
|
255
|
+
|
|
256
|
+
| Option | Type |
|
|
257
|
+
| ----------- | ------------------------------- |
|
|
258
|
+
| `onMessage` | `(msg: { role, text }) => void` |
|
|
259
|
+
| `onOpen` | `() => void` |
|
|
260
|
+
| `onClose` | `() => void` |
|
|
261
|
+
| `onError` | `(err: unknown) => void` |
|
|
262
|
+
|
|
263
|
+
Short-hand for `instance.on(...)` — useful for one-off integrations
|
|
264
|
+
that don't want to keep a handle.
|
|
265
|
+
|
|
266
|
+
---
|
|
267
|
+
|
|
268
|
+
## Resolved options (internal)
|
|
269
|
+
|
|
270
|
+
After `resolveOptions(raw)`, every field is either a default or a
|
|
271
|
+
user-supplied value. Internal modules always depend on the
|
|
272
|
+
`ResolvedOptions` shape. Key differences from the input:
|
|
273
|
+
|
|
274
|
+
- `themeMode` (ThemePreference) and `themeOverrides` (ThemeOverrides)
|
|
275
|
+
are **split** from the single `theme` input.
|
|
276
|
+
- `launcher.callout` is either a `Required<...>` object or `null`
|
|
277
|
+
(not undefined).
|
|
278
|
+
- `poweredBy` is either `PoweredByOption` or `null`.
|
|
279
|
+
- `strings` is fully populated `Record<StringKey, string>` (no
|
|
280
|
+
missing keys).
|
|
281
|
+
- `stringsOverride` is preserved separately so `App` can re-resolve
|
|
282
|
+
into a new locale at runtime.
|
|
283
|
+
- `locale` is a concrete BCP-47 tag (`"auto"` already resolved).
|
|
284
|
+
|
|
285
|
+
Full shape in `src/core/config/types.ts` `ResolvedOptions`.
|
|
286
|
+
|
|
287
|
+
---
|
|
288
|
+
|
|
289
|
+
## Server settings
|
|
290
|
+
|
|
291
|
+
`ServerConfig` (the handshake `config` field) is a subset of
|
|
292
|
+
`ChatWidgetOptions`. Server can push anything that ships under the
|
|
293
|
+
schemas above; callbacks (`onMessage` etc.) and identity fields
|
|
294
|
+
(`publicKey`) are deliberately excluded.
|
|
295
|
+
|
|
296
|
+
Merge policy (`src/core/config/merge.ts` `mergeServerConfig`):
|
|
297
|
+
|
|
298
|
+
- **Scalars** — user wins per-field. If the user didn't set it,
|
|
299
|
+
server's value applies.
|
|
300
|
+
- **Objects** — leaf merge. Server provides defaults; any user-set
|
|
301
|
+
leaf wins.
|
|
302
|
+
- **`header.actions`** — replace-whole list; server and user arrays are never concatenated.
|
|
303
|
+
- **`i18n.strings`** — locale-aware merge; flat-form overrides apply to
|
|
304
|
+
the active locale only, nested-form overrides apply per-locale.
|
|
305
|
+
|
|
306
|
+
---
|
|
307
|
+
|
|
308
|
+
## Runtime safety
|
|
309
|
+
|
|
310
|
+
The IIFE auto-boot bundle does NOT run Zod at runtime — pulling Zod
|
|
311
|
+
in would push the bundle ~70 KB gz over budget. Instead, every
|
|
312
|
+
field flows through `resolveOptions` in `src/core/config/resolve.ts`,
|
|
313
|
+
which uses `?? default` fallbacks for every option. A bad value
|
|
314
|
+
(wrong enum, malformed length, etc.) flows through and the
|
|
315
|
+
downstream consumer either uses the value as-is or substitutes a
|
|
316
|
+
sane default — the widget always mounts.
|
|
317
|
+
|
|
318
|
+
For strict validation (the dashboard / dev configurator), import
|
|
319
|
+
schemas directly from the `@helpai/elements/schema` package subpath
|
|
320
|
+
and call `.safeParse()`. That path DOES include Zod; it's only
|
|
321
|
+
loaded in admin contexts, not on every customer page.
|
|
322
|
+
|
|
323
|
+
Pass `footer: { poweredBy: { text: "" } }` to opt out of the brand attribution.
|
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# Quickstart
|
|
2
|
+
|
|
3
|
+
From zero to working chat widget in under 5 minutes.
|
|
4
|
+
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
## 1. Get your browser deployment credentials
|
|
8
|
+
|
|
9
|
+
1. Sign up at [help.ai](https://help.ai) if you haven't.
|
|
10
|
+
2. Go to **Dashboard → Deployments**.
|
|
11
|
+
3. Click **New deployment** — give it a name (e.g. "Marketing site").
|
|
12
|
+
4. Copy the public key (`agent_pk_abc123...`) and deployment UUID from the
|
|
13
|
+
generated install snippet.
|
|
14
|
+
|
|
15
|
+
> The dashboard generates a copy-paste snippet for you — feel free to use
|
|
16
|
+
> that directly. The rest of this guide assumes you want to know what
|
|
17
|
+
> each piece does.
|
|
18
|
+
|
|
19
|
+
---
|
|
20
|
+
|
|
21
|
+
## 2. Pick your install path
|
|
22
|
+
|
|
23
|
+
The widget works four ways. Pick whichever matches your site:
|
|
24
|
+
|
|
25
|
+
- **Static HTML** (marketing site, WordPress, landing page) → [path A](#path-a--static-html).
|
|
26
|
+
- **Async-loading site** (uses Google Tag Manager, Segment, etc.) → [path B](#path-b--async-loader).
|
|
27
|
+
- **React / Next.js / Remix** → the React kit in [path C](#path-c--npm).
|
|
28
|
+
- **Vue / Svelte / Nuxt** (any framework with a build step) → [path C](#path-c--npm).
|
|
29
|
+
- **Plain HTML but prefer a declarative tag** → [path D](#path-d--web-component).
|
|
30
|
+
|
|
31
|
+
All four paths land on the same widget with the same behavior. Mix and
|
|
32
|
+
match as needed.
|
|
33
|
+
|
|
34
|
+
---
|
|
35
|
+
|
|
36
|
+
## Path A — static HTML
|
|
37
|
+
|
|
38
|
+
Paste this into your `<head>`:
|
|
39
|
+
|
|
40
|
+
```html
|
|
41
|
+
<script src="https://cdn.help.ai/sdk/js/elements/latest/elements.js" data-public-key="agent_pk_abc123..." data-ai-agent-deployment-id="01900000-0000-7000-8000-000000000000" defer></script>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
That's it. Reload your page and look at the bottom-right corner.
|
|
45
|
+
|
|
46
|
+
**What `defer` does** — the script downloads in the background and runs
|
|
47
|
+
after the HTML parses. Zero impact on first contentful paint. Always
|
|
48
|
+
use `defer`.
|
|
49
|
+
|
|
50
|
+
**Available attributes** — every config option is available as a
|
|
51
|
+
kebab-case `data-*` attribute. Common ones:
|
|
52
|
+
|
|
53
|
+
```html
|
|
54
|
+
<script
|
|
55
|
+
src="https://cdn.help.ai/sdk/js/elements/latest/elements.js"
|
|
56
|
+
data-public-key="agent_pk_..."
|
|
57
|
+
data-ai-agent-deployment-id="01900000-0000-7000-8000-000000000000"
|
|
58
|
+
data-theme="dark"
|
|
59
|
+
data-position="bottom-left"
|
|
60
|
+
data-launcher-variant="pill"
|
|
61
|
+
data-launcher-label="Ask AI"
|
|
62
|
+
defer
|
|
63
|
+
></script>
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
Full list: [Installation § script data attributes](./installation.md#path-a--script-data--auto-boot).
|
|
67
|
+
|
|
68
|
+
---
|
|
69
|
+
|
|
70
|
+
## Path B — async loader
|
|
71
|
+
|
|
72
|
+
If your site already uses a tag-manager-style loader pattern (Google
|
|
73
|
+
Analytics, Segment, Intercom, etc.), you'll recognize this shape:
|
|
74
|
+
|
|
75
|
+
```html
|
|
76
|
+
<script>
|
|
77
|
+
(function (w, d) {
|
|
78
|
+
w.HelpAI =
|
|
79
|
+
w.HelpAI ||
|
|
80
|
+
function () {
|
|
81
|
+
(w.HelpAI.q = w.HelpAI.q || []).push(arguments);
|
|
82
|
+
};
|
|
83
|
+
var s = d.createElement('script');
|
|
84
|
+
s.async = 1;
|
|
85
|
+
s.src = 'https://cdn.help.ai/sdk/js/elements/latest/elements.js';
|
|
86
|
+
d.head.appendChild(s);
|
|
87
|
+
})(window, document);
|
|
88
|
+
|
|
89
|
+
HelpAI('init', { publicKey: 'agent_pk_abc123...', aiAgentDeploymentId: '01900000-0000-7000-8000-000000000000' });
|
|
90
|
+
</script>
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
**What this does:**
|
|
94
|
+
|
|
95
|
+
1. Defines `window.HelpAI` as a queue until the real bundle loads.
|
|
96
|
+
2. Kicks off the async script download.
|
|
97
|
+
3. Queues an `init` call — it'll run as soon as the bundle is ready.
|
|
98
|
+
|
|
99
|
+
You can stack more queued calls:
|
|
100
|
+
|
|
101
|
+
```js
|
|
102
|
+
HelpAI('init', { publicKey: 'agent_pk_...', aiAgentDeploymentId: '01900000-0000-7000-8000-000000000000' });
|
|
103
|
+
HelpAI('open'); // auto-opens the panel once init finishes
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Same behavior as path A, just split into two script tags so you can
|
|
107
|
+
load asynchronously.
|
|
108
|
+
|
|
109
|
+
---
|
|
110
|
+
|
|
111
|
+
## Path C — NPM
|
|
112
|
+
|
|
113
|
+
For sites with a build step (Next.js, Vite, Remix, Nuxt, SvelteKit,
|
|
114
|
+
Astro…):
|
|
115
|
+
|
|
116
|
+
```bash
|
|
117
|
+
npm install @helpai/elements
|
|
118
|
+
# or: yarn add @helpai/elements
|
|
119
|
+
# or: pnpm add @helpai/elements
|
|
120
|
+
# or: bun add @helpai/elements
|
|
121
|
+
```
|
|
122
|
+
|
|
123
|
+
### React, Next.js, Remix
|
|
124
|
+
|
|
125
|
+
The React kit renders on the server safely and is already `'use client'`; put it in the root layout:
|
|
126
|
+
|
|
127
|
+
```tsx
|
|
128
|
+
// app/layout.tsx
|
|
129
|
+
import { HelpAI } from '@helpai/elements/react';
|
|
130
|
+
|
|
131
|
+
export default function RootLayout({ children }: { children: React.ReactNode }) {
|
|
132
|
+
return (
|
|
133
|
+
<html lang='en'>
|
|
134
|
+
<body>
|
|
135
|
+
{children}
|
|
136
|
+
<HelpAI publicKey={process.env.NEXT_PUBLIC_HELPAI_KEY!} aiAgentDeploymentId={process.env.NEXT_PUBLIC_HELPAI_DEPLOYMENT_ID!} />
|
|
137
|
+
</body>
|
|
138
|
+
</html>
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
`useHelpAI()` in any component returns `{ state, ask, open, close, reset }`.
|
|
144
|
+
|
|
145
|
+
### Vue / Svelte / Angular / any bundler
|
|
146
|
+
|
|
147
|
+
Call `init(...)` once on mount and `destroy()` on unmount, or use the `<web-ai-chat>` element (path D).
|
|
148
|
+
Full framework-by-framework walkthrough: [Framework integrations](./frameworks.md).
|
|
149
|
+
|
|
150
|
+
---
|
|
151
|
+
|
|
152
|
+
## Path D — web component
|
|
153
|
+
|
|
154
|
+
Declarative tag that works in any framework or plain HTML:
|
|
155
|
+
|
|
156
|
+
```html
|
|
157
|
+
<!-- Load once, anywhere in the page -->
|
|
158
|
+
<script src="https://cdn.help.ai/sdk/js/elements/latest/elements.js" defer></script>
|
|
159
|
+
|
|
160
|
+
<!-- Use the element anywhere -->
|
|
161
|
+
<web-ai-chat public-key="agent_pk_abc123..." ai-agent-deployment-id="01900000-0000-7000-8000-000000000000" mode="inline" theme="auto"></web-ai-chat>
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
Attributes mirror the options. Changing an attribute at runtime
|
|
165
|
+
re-renders the widget with the new value.
|
|
166
|
+
|
|
167
|
+
Web components shine for:
|
|
168
|
+
|
|
169
|
+
- In-app help centers (`mode="inline"` inside a sidebar).
|
|
170
|
+
- CMS-built pages where you can paste HTML but not run JS.
|
|
171
|
+
- Declarative "just put the widget here" integrations.
|
|
172
|
+
|
|
173
|
+
---
|
|
174
|
+
|
|
175
|
+
## 3. Verify it's working
|
|
176
|
+
|
|
177
|
+
Open your page and look at the bottom-right. You should see a small
|
|
178
|
+
round chat bubble with an accent color.
|
|
179
|
+
|
|
180
|
+
- **Click it** → a panel opens with a greeting from the assistant.
|
|
181
|
+
- **Type a message** → the assistant replies token-by-token.
|
|
182
|
+
- **Close the panel** → the bubble returns.
|
|
183
|
+
- **Reload the page** → your chat history stays intact.
|
|
184
|
+
|
|
185
|
+
Something not showing up? → [Troubleshooting](./troubleshooting.md).
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## 4. Common next steps
|
|
190
|
+
|
|
191
|
+
- **Match your brand** — [Theming](./theming.md) has every color,
|
|
192
|
+
radius, and font knob.
|
|
193
|
+
- **Change the launcher label / icon** — [`launcher` options](./configuration.md#launcher).
|
|
194
|
+
- **Know who the visitor is** — pass `userContext: { id, email, name }`
|
|
195
|
+
(and `pageContext: { area }`) for personalization.
|
|
196
|
+
- **Forward chat events to analytics** — [Events & hooks](./events-and-hooks.md).
|
|
197
|
+
- **Add a second widget** (one for sales, one for support) — [Recipes
|
|
198
|
+
§ Multiple widgets](./recipes.md#multiple-widgets-on-one-page).
|
|
199
|
+
|
|
200
|
+
---
|
|
201
|
+
|
|
202
|
+
## TypeScript users
|
|
203
|
+
|
|
204
|
+
Types ship with the NPM package — no separate `@types` install needed:
|
|
205
|
+
|
|
206
|
+
```ts
|
|
207
|
+
import { init, mount, destroy, hook, type ChatWidgetOptions, type ChatWidgetInstance, type EventMap, type EventName } from '@helpai/elements';
|
|
208
|
+
```
|
|
209
|
+
|
|
210
|
+
Every option is autocomplete-friendly. Hover a field in your IDE to see
|
|
211
|
+
its doc.
|
|
212
|
+
|
|
213
|
+
---
|
|
214
|
+
|
|
215
|
+
## Environment variables
|
|
216
|
+
|
|
217
|
+
For server-rendered apps, expose the public key and deployment ID through the
|
|
218
|
+
framework's public environment variables. The values are designed for browser
|
|
219
|
+
installation; the backend accepts the authenticated pair only when both match
|
|
220
|
+
the same deployment:
|
|
221
|
+
|
|
222
|
+
| Framework | Env var prefix |
|
|
223
|
+
| ----------------------- | ---------------------- |
|
|
224
|
+
| Next.js | `NEXT_PUBLIC_*` |
|
|
225
|
+
| Vite / SvelteKit / Nuxt | `VITE_*` or `PUBLIC_*` |
|
|
226
|
+
| Remix | read from `window.ENV` |
|
|
227
|
+
| Create React App | `REACT_APP_*` |
|
|
228
|
+
|
|
229
|
+
Full security notes: [Security & privacy](./security-privacy.md).
|