@helpai/elements 1.8.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/docs/faq.md ADDED
@@ -0,0 +1,435 @@
1
+ # FAQ
2
+
3
+ Questions we hear a lot. One answer each.
4
+
5
+ ---
6
+
7
+ ## General
8
+
9
+ ### What is this widget?
10
+
11
+ A conversational AI assistant you embed on your website with one line
12
+ of code. Your visitors chat with an AI; you control the configuration
13
+ (colors, copy, model, tools) from your Help AI dashboard.
14
+
15
+ ### How much does it cost?
16
+
17
+ The widget runtime is free to embed. API usage is billed under your
18
+ Help AI plan — see [help.ai/pricing](https://help.ai/pricing).
19
+
20
+ ### How big is the bundle?
21
+
22
+ ~107 KB gzipped for the IIFE / standalone ESM (CDN asset) — chat, messenger
23
+ tabs, forms/HITL, themes, and i18n included. No external runtime dependencies.
24
+ Live budgets are enforced in CI (`.size-limit.json`).
25
+
26
+ ### Does it need a build step?
27
+
28
+ No. Path A (`<script data-*>`) works on any HTML page with zero
29
+ tooling. For framework integrations there's a proper NPM package.
30
+
31
+ ### Is the source open?
32
+
33
+ Yes — source-available. You can read it, audit it, fork it for your
34
+ own builds. Your public key gates the backend, not the frontend.
35
+
36
+ ### What browsers are supported?
37
+
38
+ Chrome/Edge 100+, Safari 15+, Firefox 100+, iOS Safari 15+. No IE11.
39
+ See [Browser support](./browser-support.md).
40
+
41
+ ---
42
+
43
+ ## Installation
44
+
45
+ ### Do I need to install NPM packages?
46
+
47
+ Only if you want to — the `<script>` tag install works without
48
+ anything. NPM is there for framework integrations (React, Next.js,
49
+ Vue, etc.) where you want typed imports + tree-shaking.
50
+
51
+ ### Can I self-host the bundle?
52
+
53
+ Yes — download `dist/help-ai/elements.js` from the NPM package (or build it
54
+ yourself) and serve it from your CDN. Point your `<script src>` at your hosted
55
+ URL. Self-hosting is also what unlocks **chunked delivery** (only changed code
56
+ re-downloads across releases) behind a single stable URL the customer never has
57
+ to change — see
58
+ [Caching, versioning & self-hosting](./installation.md#caching-versioning--self-hosting).
59
+
60
+ ### Can I use this with a tag manager (GTM)?
61
+
62
+ Yes. Use the async loader snippet ([Path B](./installation.md#path-b--async-loader-snippet))
63
+ inside a Custom HTML tag. All `HelpAI(...)` calls queue until the
64
+ bundle lands.
65
+
66
+ ### Does it work in an iframe?
67
+
68
+ Yes — and there's an optional `presentation.iframe: true` flag that wraps the
69
+ widget in its OWN iframe for extra isolation. See
70
+ [Configuration § presentation.iframe](./configuration.md#presentationiframe).
71
+
72
+ ### Does it work in shadow DOM?
73
+
74
+ Yes. The widget **creates** a shadow DOM for its own internals, but
75
+ you can also mount the widget inside another shadow root (e.g., a
76
+ custom element on your page). Everything just works.
77
+
78
+ ### Does it work with React / Next.js?
79
+
80
+ Yes. Full walkthrough: [Framework integrations § Next.js](./frameworks.md#nextjs).
81
+
82
+ ### Does it work with Vue / Svelte / SolidJS / Angular?
83
+
84
+ Yes. See [Framework integrations](./frameworks.md).
85
+
86
+ ### Does it work with WordPress / Shopify / Webflow / Squarespace?
87
+
88
+ Yes. [Framework integrations § CMS](./frameworks.md#wordpress).
89
+
90
+ ---
91
+
92
+ ## Customization
93
+
94
+ ### Can I change the launcher icon?
95
+
96
+ Yes. Pick from presets (`chat`, `spark`, `message`, `help`, `wand`)
97
+ or pass raw SVG. See [Theming § Icons](./theming.md#icons).
98
+
99
+ ### Can I match my brand colors?
100
+
101
+ Yes. Set `theme.accent`, `theme.accentText`, `theme.radius`,
102
+ `theme.fontFamily`. See [Theming § Colors](./theming.md#color-overrides).
103
+
104
+ ### Can I change the font?
105
+
106
+ Yes, via `theme.fontFamily`. The widget uses Inter by default but
107
+ respects any CSS font stack you provide.
108
+
109
+ ### Can I hide the launcher and open the widget from my own button?
110
+
111
+ Yes. Set `launcher: { hidden: true }`, then call `chat.open()` from
112
+ your button's click handler. [Recipes § Custom launcher](./recipes.md#custom-launcher-button).
113
+
114
+ ### Can I change the welcome message?
115
+
116
+ Yes — from your Help AI dashboard (**Deployment → Welcome**). The
117
+ widget just renders what the backend sends.
118
+
119
+ ### Can I override UI strings?
120
+
121
+ Yes, per-locale or flat. See [Theming § Strings](./theming.md#strings-overrides).
122
+
123
+ ### Can I have multiple widgets on one page?
124
+
125
+ Yes — with distinct `widgetId` values. Each gets its own chat
126
+ thread, storage, and events. [Recipes § Multi-widget](./recipes.md#multiple-widgets-on-one-page).
127
+
128
+ ### Can I show the widget only on certain pages?
129
+
130
+ Yes — just skip the `init()` call on pages where you don't want it.
131
+ Or conditionally mount/unmount based on the URL.
132
+ [Recipes § Conditional show](./recipes.md#conditionally-show-based-on-url).
133
+
134
+ ### Can I use it in a specific language?
135
+
136
+ Yes. Force via `i18n.locale: 'fr-CA'`. Let users switch via
137
+ `i18n.availableLocales: ['en', 'fr', 'es']`. Full details: [Theming §
138
+ Internationalization](./theming.md#internationalization).
139
+
140
+ ### Can I change the widget's position on mobile?
141
+
142
+ Not per-breakpoint via options, but you can use `update()` to change
143
+ it based on `window.innerWidth`:
144
+
145
+ ```ts
146
+ function presentationForViewport() {
147
+ return {
148
+ mode: 'floating' as const,
149
+ position: window.innerWidth < 640 ? ('bottom-right' as const) : ('bottom-left' as const),
150
+ };
151
+ }
152
+
153
+ const chat = init({ publicKey: '...', aiAgentDeploymentId: '01900000-0000-7000-8000-000000000000', presentation: presentationForViewport() });
154
+
155
+ function updatePosition() {
156
+ chat.update({ presentation: presentationForViewport() });
157
+ }
158
+ updatePosition();
159
+ window.addEventListener('resize', updatePosition);
160
+ ```
161
+
162
+ ---
163
+
164
+ ## Data & privacy
165
+
166
+ ### What data does the widget send to Help AI?
167
+
168
+ Every turn: the visitor's message, any attachments, the widget
169
+ settings snapshot (locale, theme preference, panel size), and an
170
+ anonymous `visitorId`. The default anonymous usage tracker also sends
171
+ allowlisted event metadata through 1×1 pixel requests; it never sends message
172
+ text or form values and can be disabled with `tracking.enabled: false`. GPC and
173
+ DNT disable it automatically. No cookies or fingerprinting.
174
+
175
+ Full breakdown: [Security & privacy § data collected](./security-privacy.md#what-data-the-widget-collects).
176
+
177
+ ### Does the widget use cookies?
178
+
179
+ No cookies. The default persistence adapter uses `localStorage`, and anonymous
180
+ usage tracking is enabled by default. Cookie absence alone does not determine
181
+ your consent obligations; if your policy requires consent before analytics,
182
+ mount with `tracking.enabled: false` and enable it only after consent. Users in
183
+ Private / Incognito mode still get the widget, but persistence behavior depends
184
+ on the browser.
185
+
186
+ ### Where is the data stored?
187
+
188
+ Help AI API + your deployment's configured model provider.
189
+
190
+ ### Is the widget GDPR-compliant?
191
+
192
+ It stores data about identified users (when you pass `user.id`) or
193
+ anonymous visitors. Your DPA (Data Processing Agreement) with Help
194
+ AI covers the processing terms. For consent management, see
195
+ [Recipes § Gate behind consent](./recipes.md#gate-the-widget-behind-consent).
196
+
197
+ ### Can visitors delete their chat history?
198
+
199
+ Yes — clicking the trash icon in the panel starts a new conversation
200
+ (the old one becomes inaccessible from the client). For full
201
+ deletion from the backend, they contact support@help.ai (or your
202
+ equivalent data controller).
203
+
204
+ ### Can I disable conversation and UI persistence?
205
+
206
+ Yes — pass a custom in-memory storage adapter. Adapter-managed identity,
207
+ conversation, draft, preference, and UI state then evaporates on reload. The
208
+ optional logger debug level is separate: calling `setDebug` persists
209
+ `helpai.debug` directly in `localStorage` until the host clears it.
210
+ [Recipes § Custom storage adapter](./recipes.md#custom-storage-adapter).
211
+
212
+ ### Does the widget track visitors across sites?
213
+
214
+ No. The `visitorId` is per browser origin and brand, shared by all Help AI
215
+ widgets and deployments on that origin. A visitor using the widget on `foo.com`
216
+ is a different visitor on `bar.com` even if both sites share the same Help AI
217
+ deployment.
218
+
219
+ ---
220
+
221
+ ## Integration
222
+
223
+ ### How do I pass the current user's identity?
224
+
225
+ ```ts
226
+ init({
227
+ userContext: { id: user.id, email: user.email, name: user.name },
228
+ });
229
+ ```
230
+
231
+ `userContext` (and `pageContext`) is host-asserted context for the AI,
232
+ not an auth credential. Browser public access uses the matching
233
+ `publicKey` + `aiAgentDeploymentId` pair, or the deployment ID alone for
234
+ intentional guest mode.
235
+ See [Recipes § Logged-in user personalization](./recipes.md#logged-in-user-personalization).
236
+
237
+ ### How do I integrate with my analytics (GA / Segment / Mixpanel)?
238
+
239
+ One-line pre-boot hook forwards every event:
240
+
241
+ ```html
242
+ <script>
243
+ window.HelpAIHooks = window.HelpAIHooks || [];
244
+ window.HelpAIHooks.push([
245
+ '*',
246
+ '*',
247
+ (inst, event, data) => {
248
+ analytics.track(`chat_${event}`, { widget: inst.widgetId, data });
249
+ },
250
+ ]);
251
+ </script>
252
+ ```
253
+
254
+ Full examples: [Recipes § Analytics forwarding](./recipes.md#analytics-forwarding).
255
+
256
+ ### How do I capture errors in Sentry / Datadog?
257
+
258
+ ```ts
259
+ import { hook } from '@helpai/elements';
260
+
261
+ hook('*', 'error', (inst, _event, err) => {
262
+ Sentry.captureException(err, { tags: { widget: inst.widgetId } });
263
+ });
264
+ ```
265
+
266
+ ### Can I read the chat transcript server-side?
267
+
268
+ Yes — our REST API exposes per-visitor / per-chat endpoints. Contact
269
+ support for the API spec. Client-side, build your own log:
270
+
271
+ ```ts
272
+ const transcript = [];
273
+ chat.on('message', (m) => transcript.push({ ...m, at: Date.now() }));
274
+ ```
275
+
276
+ ### How do I send the user a pre-filled first message?
277
+
278
+ Configure **welcome suggestion chips** in your Help AI dashboard.
279
+ Clicking a chip fills the composer with its text to edit before sending
280
+ (or set `behavior.autoSendSuggestions: true` to send on tap). This is the
281
+ intended pattern for "conversation starter" UX.
282
+
283
+ ### How do I trigger chat from a specific user action (e.g., after clicking a CTA)?
284
+
285
+ ```ts
286
+ const chat = init({ publicKey: '...', aiAgentDeploymentId: '01900000-0000-7000-8000-000000000000' });
287
+
288
+ document.querySelector('#pricing-cta').addEventListener('click', () => {
289
+ chat.open();
290
+ });
291
+ ```
292
+
293
+ ---
294
+
295
+ ## Behavior
296
+
297
+ ### Why does the widget open automatically sometimes?
298
+
299
+ When you set `behavior.startMinimized: false` explicitly. Otherwise it defaults
300
+ to closed, and remembers the user's last open/close state across
301
+ reloads.
302
+
303
+ ### Why does the panel restore from fullscreen when I reload?
304
+
305
+ User's last size tier is remembered. If they closed while in
306
+ fullscreen, it reopens in fullscreen. If they want to reset,
307
+ clicking "New conversation" resets the layout too (or they can click
308
+ the ⛶ button to exit fullscreen).
309
+
310
+ ### Why doesn't the widget show on Safari private mode?
311
+
312
+ It does — but `localStorage` might be ephemeral, meaning chat history
313
+ disappears when the tab closes. Everything else works.
314
+
315
+ ### Why do I see the "What can you do?" suggestion only sometimes?
316
+
317
+ Suggestion chips are server-configured per deployment. The backend
318
+ decides what to show based on:
319
+
320
+ - **New conversation** — typically "What can you do?", "Show me pricing",
321
+ etc.
322
+ - **Resumed chat** — typically "Continue where we left off" or
323
+ nothing.
324
+
325
+ If you're seeing unexpected ones, check your deployment's
326
+ "Welcome → Suggestions" config in the dashboard.
327
+
328
+ ### Why does expanding the panel not work on mobile?
329
+
330
+ The automatic tier uses fullscreen below 640 px, normal from 640–899 px,
331
+ and expanded from 900 px by default. To change the desktop breakpoint:
332
+
333
+ ```ts
334
+ init({ presentation: { size: { autoSizeBreakpoint: 1200 } } }); // desktop expands at 1200px+
335
+ ```
336
+
337
+ ### Why does my custom SVG icon render blank?
338
+
339
+ Probably malformed SVG. The widget parses icons via `DOMParser` —
340
+ verify yours is valid SVG 2.x. Use `<path fill="currentColor">` for
341
+ theming to work.
342
+
343
+ ### Why does Enter send when I'm composing CJK (Japanese/Chinese/Korean)?
344
+
345
+ It shouldn't — the widget checks `isComposing`. If it's still
346
+ happening, report a bug. Workaround: use `Shift+Enter` for a
347
+ newline.
348
+
349
+ ---
350
+
351
+ ## Billing & plans
352
+
353
+ ### Does the widget consume API credits?
354
+
355
+ Yes — every message sent to the AI uses your Help AI API credits.
356
+ See [help.ai/pricing](https://help.ai/pricing).
357
+
358
+ ### How do I cap spend per visitor?
359
+
360
+ In your Help AI dashboard: **Deployment → Limits → Per-visitor cap**.
361
+ When a visitor hits the cap, the widget shows "This conversation is
362
+ closed. Start a new conversation?" (via `canContinue: false`).
363
+
364
+ ### What happens if my account runs out of credits?
365
+
366
+ The widget still renders; users see an error when they try to send.
367
+ The `error` event fires with the details. Configure a fallback UX:
368
+
369
+ ```ts
370
+ init({
371
+ onError: (err) => {
372
+ // Show a message or fall back to email form
373
+ showFallbackContactForm();
374
+ },
375
+ });
376
+ ```
377
+
378
+ ---
379
+
380
+ ## Versioning
381
+
382
+ ### How do I know what version I'm running?
383
+
384
+ ```js
385
+ console.log(window.HelpAI?.version);
386
+ // Or:
387
+ import { version } from '@helpai/elements';
388
+ console.log(version);
389
+ ```
390
+
391
+ ### How do I pin to a specific version?
392
+
393
+ ```html
394
+ <script src="https://cdn.help.ai/v1.2.0/elements.js" defer></script>
395
+ ```
396
+
397
+ Or `v1` for the latest v1.x.x (auto-patches but no major breaks).
398
+
399
+ ### When are breaking changes released?
400
+
401
+ Only in major version bumps. Minor versions are additive. Patch
402
+ versions are bug fixes. Semver throughout.
403
+
404
+ ### How do I upgrade?
405
+
406
+ If you use the floating CDN URL, automatically. If pinned, update
407
+ the version in your `<script>` tag. NPM users: `npm update
408
+ @helpai/elements`.
409
+
410
+ ### Where's the changelog?
411
+
412
+ [github.com/help-ai/elements/releases](https://github.com/help-ai/elements/releases).
413
+
414
+ ---
415
+
416
+ ## Support
417
+
418
+ ### How do I contact support?
419
+
420
+ - **Email**: [support@help.ai](mailto:support@help.ai)
421
+ - **Docs**: you're reading them
422
+ - **Status**: [help.ai/status](https://help.ai/status)
423
+ - **Bugs**: [GitHub Issues](https://github.com/help-ai/elements/issues)
424
+
425
+ ### How fast is support?
426
+
427
+ - Email: within 24 hours on weekdays.
428
+ - Critical outages: tracked on status page in real-time.
429
+ - Enterprise customers: SLA per contract.
430
+
431
+ ### Can I get a custom build?
432
+
433
+ Yes — contact [sales@help.ai](mailto:sales@help.ai) for enterprise
434
+ options. Custom brands, custom CDN, custom features are all on the
435
+ table.