@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/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 +84 -3
- package/index.mjs +13 -13
- 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 +14 -14
|
@@ -0,0 +1,302 @@
|
|
|
1
|
+
# Browser support
|
|
2
|
+
|
|
3
|
+
## Supported browsers
|
|
4
|
+
|
|
5
|
+
Baseline support matches modern evergreen browsers:
|
|
6
|
+
|
|
7
|
+
| Browser | Minimum version | Notes |
|
|
8
|
+
| ---------------- | --------------- | -------------------------- |
|
|
9
|
+
| Chrome / Edge | 100 | Released April 2022 |
|
|
10
|
+
| Firefox | 100 | Released May 2022 |
|
|
11
|
+
| Safari | 15 | macOS Big Sur + / iOS 15 + |
|
|
12
|
+
| Opera | 86 | Chromium-based |
|
|
13
|
+
| Samsung Internet | 17 | Android |
|
|
14
|
+
|
|
15
|
+
Chromium-based browsers (Brave, Vivaldi, Arc, DuckDuckGo Browser)
|
|
16
|
+
work if their underlying Chromium version is ≥ 100.
|
|
17
|
+
|
|
18
|
+
## Explicitly not supported
|
|
19
|
+
|
|
20
|
+
- **Internet Explorer** (any version).
|
|
21
|
+
- **Legacy Edge** (pre-Chromium, EdgeHTML).
|
|
22
|
+
- **Opera Mini** (proxy-rendered, no JS).
|
|
23
|
+
- **UC Browser** (ancient WebKit fork).
|
|
24
|
+
|
|
25
|
+
If you need to support IE or similar, the widget won't render. Detect
|
|
26
|
+
and show a fallback contact form:
|
|
27
|
+
|
|
28
|
+
```js
|
|
29
|
+
const supportsWidget = 'attachShadow' in Element.prototype && 'fetch' in window && typeof ReadableStream === 'function';
|
|
30
|
+
|
|
31
|
+
if (!supportsWidget) {
|
|
32
|
+
document.getElementById('legacy-contact').style.display = 'block';
|
|
33
|
+
}
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
---
|
|
37
|
+
|
|
38
|
+
## Features used
|
|
39
|
+
|
|
40
|
+
The widget relies on:
|
|
41
|
+
|
|
42
|
+
| API | Feature detection | Why |
|
|
43
|
+
| ------------------------------ | ---------------------------------------------- | ----------------------------------------------------------------- |
|
|
44
|
+
| Shadow DOM (`attachShadow`) | `'attachShadow' in Element.prototype` | Widget rendering isolation |
|
|
45
|
+
| Custom Elements | `typeof customElements` | `<web-ai-chat>` element |
|
|
46
|
+
| Constructable Stylesheets | `'adoptedStyleSheets' in ShadowRoot.prototype` | Efficient CSS adoption (falls back to `<style>`) |
|
|
47
|
+
| ES Modules | Native | NPM + web-component sub-entry |
|
|
48
|
+
| `fetch` | Native | API calls |
|
|
49
|
+
| `ReadableStream` | Native | Streaming responses |
|
|
50
|
+
| `TextDecoder` / `TextEncoder` | Native | SSE frame parsing |
|
|
51
|
+
| Async generators (`for await`) | Native | Stream consumers |
|
|
52
|
+
| CSS custom properties | `:root { --var: ... }` | Theming |
|
|
53
|
+
| CSS `contain: size` | Supported everywhere we support | Inline-mode layout containment |
|
|
54
|
+
| `IntersectionObserver` | Native | Auto-scroll behaviour |
|
|
55
|
+
| `matchMedia` | Native | `prefers-color-scheme`, `prefers-reduced-motion`, touch detection |
|
|
56
|
+
| `MediaRecorder` | Feature-detected | Voice input (server mode) |
|
|
57
|
+
| Web Speech API | Feature-detected | Voice input (local mode) |
|
|
58
|
+
| `navigator.vibrate` | Feature-detected | Haptic feedback (Android) |
|
|
59
|
+
| `AudioContext` | Feature-detected | Sound effects |
|
|
60
|
+
|
|
61
|
+
Features marked "Feature-detected" gracefully degrade when unavailable
|
|
62
|
+
— e.g., on iOS 17.3 and below, `navigator.vibrate` is missing, so
|
|
63
|
+
haptics silently no-op.
|
|
64
|
+
|
|
65
|
+
---
|
|
66
|
+
|
|
67
|
+
## Mobile specifics
|
|
68
|
+
|
|
69
|
+
### iOS Safari
|
|
70
|
+
|
|
71
|
+
- **Full support** on iOS 15+.
|
|
72
|
+
- **Haptics** — WebKit doesn't expose `navigator.vibrate`. We use a
|
|
73
|
+
programmatic `<input type="checkbox" switch>` click on iOS 17.4+ to
|
|
74
|
+
trigger a single haptic tick. Custom patterns flatten to one tick.
|
|
75
|
+
- **Voice (local)** — `SpeechRecognition` is available but quality
|
|
76
|
+
varies. Recommend `features.voice: "server"` for production.
|
|
77
|
+
- **Keyboard avoidance** — when the on-screen keyboard appears, the
|
|
78
|
+
panel auto-adjusts to stay visible.
|
|
79
|
+
- **Text-entry focus** — the composer, Help search, and form/HITL fields keep a
|
|
80
|
+
minimum 16px computed font on touch devices so focusing them does not trigger
|
|
81
|
+
iOS page zoom. Each uses its existing border as the single focus indicator.
|
|
82
|
+
- **Viewport units** — we use `dvh` where supported (iOS 16+) and
|
|
83
|
+
fall back to `vh` below.
|
|
84
|
+
|
|
85
|
+
### Android Chrome
|
|
86
|
+
|
|
87
|
+
- **Full support**.
|
|
88
|
+
- **Haptics** — `navigator.vibrate` supports both single and pattern
|
|
89
|
+
vibrations.
|
|
90
|
+
- **Voice (local)** — Web Speech works well.
|
|
91
|
+
|
|
92
|
+
### Samsung Internet + other Android browsers
|
|
93
|
+
|
|
94
|
+
- **Samsung Internet 17+** — Chromium-based, full support.
|
|
95
|
+
- **Firefox Android** — tested and working.
|
|
96
|
+
- **Brave / DuckDuckGo** — Chromium-based, work identically to Chrome.
|
|
97
|
+
|
|
98
|
+
---
|
|
99
|
+
|
|
100
|
+
## Accessibility
|
|
101
|
+
|
|
102
|
+
### Keyboard navigation
|
|
103
|
+
|
|
104
|
+
- **Tab** rotates through all interactive elements (launcher, header
|
|
105
|
+
buttons, menu items, textarea, send, history rows).
|
|
106
|
+
- **Shift+Tab** reverses.
|
|
107
|
+
- **Enter / Space** on the launcher opens the panel.
|
|
108
|
+
- **Escape** closes the panel (or exits fullscreen in inline mode).
|
|
109
|
+
- **Arrow Up / Down** navigates within popover menus.
|
|
110
|
+
- **Home / End** jump to first / last menu item.
|
|
111
|
+
- **Enter** on a menu item selects.
|
|
112
|
+
|
|
113
|
+
### Screen readers
|
|
114
|
+
|
|
115
|
+
- Every icon-only button has an `aria-label`.
|
|
116
|
+
- Popover menus use `role="menu"` + `role="menuitem"` with proper
|
|
117
|
+
`aria-haspopup` + `aria-expanded`.
|
|
118
|
+
- Switch-style actions carry `aria-pressed`.
|
|
119
|
+
- Active language / theme options use `aria-current="true"`.
|
|
120
|
+
- The panel is a `role="dialog"` with `aria-modal="false"`
|
|
121
|
+
(non-blocking) and focus trap.
|
|
122
|
+
|
|
123
|
+
### `prefers-reduced-motion`
|
|
124
|
+
|
|
125
|
+
When the user has motion reduced:
|
|
126
|
+
|
|
127
|
+
- Launcher callout animations disabled.
|
|
128
|
+
- Panel open/close animations shortened.
|
|
129
|
+
- Haptic feedback disabled.
|
|
130
|
+
- Sound volume halved.
|
|
131
|
+
|
|
132
|
+
### `prefers-color-scheme`
|
|
133
|
+
|
|
134
|
+
The default theme mode is `"auto"` — follows the OS preference.
|
|
135
|
+
Users can override via the in-widget theme picker.
|
|
136
|
+
|
|
137
|
+
### Touch vs pointer
|
|
138
|
+
|
|
139
|
+
The widget detects touch capability via
|
|
140
|
+
`matchMedia("(hover: none) and (pointer: coarse)")` and enables
|
|
141
|
+
haptics only on touch devices. Desktop users with mice never get
|
|
142
|
+
vibration prompts.
|
|
143
|
+
|
|
144
|
+
---
|
|
145
|
+
|
|
146
|
+
## Feature-detection code
|
|
147
|
+
|
|
148
|
+
If you want to check for widget compatibility before installing:
|
|
149
|
+
|
|
150
|
+
```js
|
|
151
|
+
function helpaiSupported() {
|
|
152
|
+
if (typeof window === 'undefined') return false;
|
|
153
|
+
if (!('customElements' in window)) return false;
|
|
154
|
+
if (!('attachShadow' in Element.prototype)) return false;
|
|
155
|
+
if (!('fetch' in window)) return false;
|
|
156
|
+
if (typeof ReadableStream !== 'function') return false;
|
|
157
|
+
if (typeof Promise !== 'function') return false;
|
|
158
|
+
return true;
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
if (helpaiSupported()) {
|
|
162
|
+
// Load the widget
|
|
163
|
+
const s = document.createElement('script');
|
|
164
|
+
s.src = 'https://cdn.help.ai/sdk/js/elements/latest/elements.js';
|
|
165
|
+
s.setAttribute('data-public-key', 'agent_pk_...');
|
|
166
|
+
s.setAttribute('data-ai-agent-deployment-id', '01900000-0000-7000-8000-000000000000');
|
|
167
|
+
s.defer = true;
|
|
168
|
+
document.head.appendChild(s);
|
|
169
|
+
} else {
|
|
170
|
+
// Show fallback
|
|
171
|
+
document.getElementById('legacy-chat-fallback').style.display = 'block';
|
|
172
|
+
}
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
---
|
|
176
|
+
|
|
177
|
+
## Polyfills
|
|
178
|
+
|
|
179
|
+
We don't ship any — the feature set is chosen so that every supported
|
|
180
|
+
browser has native implementations.
|
|
181
|
+
|
|
182
|
+
If you need to support an older browser via your own polyfills
|
|
183
|
+
(`core-js`, `whatwg-fetch`, etc.), the widget should work, but we
|
|
184
|
+
don't test this path. File an issue if something breaks and we'll
|
|
185
|
+
look.
|
|
186
|
+
|
|
187
|
+
---
|
|
188
|
+
|
|
189
|
+
## Performance targets
|
|
190
|
+
|
|
191
|
+
On a mid-tier laptop (M1 MacBook Air, 2020):
|
|
192
|
+
|
|
193
|
+
| Metric | Target | Measured (current) |
|
|
194
|
+
| ------------------------------------ | -------- | ------------------ |
|
|
195
|
+
| Bundle download (gzipped) | < 110 KB | ~107 KB |
|
|
196
|
+
| First byte to first bubble painted | < 200ms | ~150ms |
|
|
197
|
+
| Time to interactive (first open) | < 1s | ~600ms |
|
|
198
|
+
| Per-token stream render latency | < 5ms | ~2ms |
|
|
199
|
+
| Panel close → FAB visible transition | < 200ms | ~180ms |
|
|
200
|
+
|
|
201
|
+
On a 2019 Android mid-range (Galaxy A30):
|
|
202
|
+
|
|
203
|
+
| Metric | Target | Measured |
|
|
204
|
+
| ---------------------------------- | ------- | -------- |
|
|
205
|
+
| First byte to first bubble painted | < 500ms | ~350ms |
|
|
206
|
+
| Time to interactive (first open) | < 2s | ~1.1s |
|
|
207
|
+
|
|
208
|
+
We run Lighthouse audits on every release; the widget never regresses
|
|
209
|
+
the host page's performance score by more than 2 points.
|
|
210
|
+
|
|
211
|
+
---
|
|
212
|
+
|
|
213
|
+
## Degraded modes
|
|
214
|
+
|
|
215
|
+
### Offline
|
|
216
|
+
|
|
217
|
+
- If the bundle is cached, the widget renders.
|
|
218
|
+
- Attempting to send fires an `error` event. Listen to provide a
|
|
219
|
+
fallback:
|
|
220
|
+
```ts
|
|
221
|
+
init({
|
|
222
|
+
onError: (err) => {
|
|
223
|
+
if (!navigator.onLine) {
|
|
224
|
+
alert('You appear to be offline. Please try again later.');
|
|
225
|
+
}
|
|
226
|
+
},
|
|
227
|
+
});
|
|
228
|
+
```
|
|
229
|
+
- Cached chats remain viewable.
|
|
230
|
+
- When the connection returns, the widget continues working
|
|
231
|
+
automatically.
|
|
232
|
+
|
|
233
|
+
### Slow networks
|
|
234
|
+
|
|
235
|
+
- The streaming pipeline is resilient to per-frame delays.
|
|
236
|
+
- If the stream gets stuck, the user sees a "thinking…" indicator.
|
|
237
|
+
- User can click Stop to abort and retry.
|
|
238
|
+
|
|
239
|
+
### No localStorage (private mode on some browsers)
|
|
240
|
+
|
|
241
|
+
- The widget falls back to a no-op storage adapter (writes succeed
|
|
242
|
+
but don't persist).
|
|
243
|
+
- Chat history doesn't persist across reloads.
|
|
244
|
+
- Everything else works.
|
|
245
|
+
|
|
246
|
+
### Old browsers
|
|
247
|
+
|
|
248
|
+
- The widget shows nothing (custom elements / shadow DOM aren't
|
|
249
|
+
available). Your page renders normally; the widget is just absent.
|
|
250
|
+
- Feature-detect if you want to show a fallback.
|
|
251
|
+
|
|
252
|
+
---
|
|
253
|
+
|
|
254
|
+
## Device form factors
|
|
255
|
+
|
|
256
|
+
Tested on:
|
|
257
|
+
|
|
258
|
+
- **Desktop** (1280×720 minimum — smaller works but cramped in
|
|
259
|
+
floating mode).
|
|
260
|
+
- **Tablet** (iPad landscape/portrait, Android tablets).
|
|
261
|
+
- **Mobile** (360×640 minimum — iPhone SE, Android Pixel).
|
|
262
|
+
- **Foldable** (Galaxy Z Fold — adapts via `matchMedia`).
|
|
263
|
+
|
|
264
|
+
Responsive behavior:
|
|
265
|
+
|
|
266
|
+
- `initialSize: "auto"` expands the panel on wide viewports
|
|
267
|
+
(`≥ autoSizeBreakpoint`, default 900px).
|
|
268
|
+
- Below the breakpoint, the panel defaults to a phone-friendly
|
|
269
|
+
compact size.
|
|
270
|
+
|
|
271
|
+
---
|
|
272
|
+
|
|
273
|
+
## Known limitations
|
|
274
|
+
|
|
275
|
+
- **iOS Safari viewport units** — we use `dvh` when supported (iOS
|
|
276
|
+
16+). On older iOS, use `100vh` fallback may over-expand by the
|
|
277
|
+
browser chrome height.
|
|
278
|
+
- **Android haptics vary by device** — OEM customizations (Samsung,
|
|
279
|
+
Xiaomi) sometimes override or weaken `navigator.vibrate`. Not
|
|
280
|
+
much we can do.
|
|
281
|
+
- **Firefox streaming markdown** — Firefox's `streaming-markdown`
|
|
282
|
+
runs ~5% slower than Chromium on long streams. Imperceptible unless
|
|
283
|
+
streaming tens of thousands of tokens.
|
|
284
|
+
- **Dark reader extensions** — "Dark Reader" (the popular dark-mode
|
|
285
|
+
browser extension) can invert the widget's colors even in dark
|
|
286
|
+
mode. Workaround: users disable Dark Reader for your site.
|
|
287
|
+
|
|
288
|
+
---
|
|
289
|
+
|
|
290
|
+
## Reporting compatibility issues
|
|
291
|
+
|
|
292
|
+
Found a browser where the widget misbehaves? Please file an issue
|
|
293
|
+
with:
|
|
294
|
+
|
|
295
|
+
- Browser name + version.
|
|
296
|
+
- OS + version.
|
|
297
|
+
- Device type (desktop / mobile / tablet).
|
|
298
|
+
- Steps to reproduce.
|
|
299
|
+
- Screenshot or screen recording.
|
|
300
|
+
- Console output.
|
|
301
|
+
|
|
302
|
+
[github.com/help-ai/elements/issues](https://github.com/help-ai/elements/issues)
|