@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
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.
|