Skip to content

FAQ

Short answers to common questions.

Last updated

Questions we hear a lot. One answer each.


General#

What is this widget?#

A conversational AI assistant you embed on your website with one line of code. Your visitors chat with an AI; you control the configuration (colors, copy, model, tools) from your Help AI dashboard.

How much does it cost?#

The widget runtime is free to embed. API usage is billed under your Help AI plan — see help.ai/pricing (opens another site).

How big is the bundle?#

~107 KB gzipped for the IIFE / standalone ESM (CDN asset) — chat, messenger tabs, forms/HITL, themes, and i18n included. No external runtime dependencies. Live budgets are enforced in CI (.size-limit.json).

Does it need a build step?#

No. Path A (<script data-*>) works on any HTML page with zero tooling. For framework integrations there's a proper NPM package.

Is the source open?#

Yes — source-available. You can read it, audit it, fork it for your own builds. Your public key gates the backend, not the frontend.

What browsers are supported?#

Chrome/Edge 100+, Safari 15+, Firefox 100+, iOS Safari 15+. No IE11. See Browser support.


Installation#

Do I need to install NPM packages?#

Only if you want to — the <script> tag install works without anything. NPM is there for framework integrations (React, Next.js, Vue, etc.) where you want typed imports + tree-shaking.

Can I self-host the bundle?#

Yes — download dist/help-ai/elements.js from the NPM package (or build it yourself) and serve it from your CDN. Point your <script src> at your hosted URL. Self-hosting is also what unlocks chunked delivery (only changed code re-downloads across releases) behind a single stable URL the customer never has to change — see Caching, versioning & self-hosting.

Can I use this with a tag manager (GTM)?#

Yes. Use the async loader snippet (Path B) inside a Custom HTML tag. All HelpAI(...) calls queue until the bundle lands.

Does it work in an iframe?#

Yes — and there's an optional presentation.iframe: true flag that wraps the widget in its OWN iframe for extra isolation. See Configuration § presentation.iframe.

Does it work in shadow DOM?#

Yes. The widget creates a shadow DOM for its own internals, but you can also mount the widget inside another shadow root (e.g., a custom element on your page). Everything just works.

Does it work with React / Next.js?#

Yes. Full walkthrough: Framework integrations § Next.js.

Does it work with Vue / Svelte / SolidJS / Angular?#

Yes. See Framework integrations.

Does it work with WordPress / Shopify / Webflow / Squarespace?#

Yes. Framework integrations § CMS.


Customization#

Can I change the launcher icon?#

Yes. Pick from presets (chat, spark, message, help, wand) or pass raw SVG. See Theming § Icons.

Can I match my brand colors?#

Yes. Set theme.accent, theme.accentText, theme.radius, theme.fontFamily. See Theming § Colors.

Can I change the font?#

Yes, via theme.fontFamily. The widget uses Inter by default but respects any CSS font stack you provide.

Can I hide the launcher and open the widget from my own button?#

Yes. Set launcher: { hidden: true }, then call chat.open() from your button's click handler. Recipes § Custom launcher.

Can I change the welcome message?#

Yes — from your Help AI dashboard (Deployment → Welcome). The widget just renders what the backend sends.

Can I override UI strings?#

Yes, per-locale or flat. See Theming § Strings.

Can I have multiple widgets on one page?#

Yes — with distinct widgetId values. Each gets its own chat thread, storage, and events. Recipes § Multi-widget.

Can I show the widget only on certain pages?#

Yes — just skip the init() call on pages where you don't want it. Or conditionally mount/unmount based on the URL. Recipes § Conditional show.

Can I use it in a specific language?#

Yes. Force via i18n.locale: 'fr-CA'. Let users switch via i18n.availableLocales: ['en', 'fr', 'es']. Full details: Theming § Internationalization.

Can I change the widget's position on mobile?#

Not per-breakpoint via options, but you can use update() to change it based on window.innerWidth:

ts
function presentationForViewport() {
  return {
    mode: 'floating' as const,
    position: window.innerWidth < 640 ? ('bottom-right' as const) : ('bottom-left' as const),
  };
}

const chat = init({ publicKey: '...', aiAgentDeploymentId: '01900000-0000-7000-8000-000000000000', presentation: presentationForViewport() });

function updatePosition() {
  chat.update({ presentation: presentationForViewport() });
}
updatePosition();
window.addEventListener('resize', updatePosition);

Data & privacy#

What data does the widget send to Help AI?#

Every turn: the visitor's message, any attachments, the widget settings snapshot (locale, theme preference, panel size), and an anonymous visitorId. The default anonymous usage tracker also sends allowlisted event metadata through 1×1 pixel requests; it never sends message text or form values and can be disabled with tracking.enabled: false. GPC and DNT disable it automatically. No cookies or fingerprinting.

Full breakdown: Security & privacy § data collected.

Does the widget use cookies?#

No cookies. The default persistence adapter uses localStorage, and anonymous usage tracking is enabled by default. Cookie absence alone does not determine your consent obligations; if your policy requires consent before analytics, mount with tracking.enabled: false and enable it only after consent. Users in Private / Incognito mode still get the widget, but persistence behavior depends on the browser.

Where is the data stored?#

Help AI API + your deployment's configured model provider.

Is the widget GDPR-compliant?#

It stores data about identified users (when you pass user.id) or anonymous visitors. Your DPA (Data Processing Agreement) with Help AI covers the processing terms. For consent management, see Recipes § Gate behind consent.

Can visitors delete their chat history?#

Yes — clicking the trash icon in the panel starts a new conversation (the old one becomes inaccessible from the client). For full deletion from the backend, they contact support@help.ai (or your equivalent data controller).

Can I disable conversation and UI persistence?#

Yes — pass a custom in-memory storage adapter. Adapter-managed identity, conversation, draft, preference, and UI state then evaporates on reload. The optional logger debug level is separate: calling setDebug persists helpai.debug directly in localStorage until the host clears it. Recipes § Custom storage adapter.

Does the widget track visitors across sites?#

No. The visitorId is per browser origin and brand, shared by all Help AI widgets and deployments on that origin. A visitor using the widget on foo.com is a different visitor on bar.com even if both sites share the same Help AI deployment.


Integration#

How do I pass the current user's identity?#

ts
init({
  userContext: { id: user.id, email: user.email, name: user.name },
});

userContext (and pageContext) is host-asserted context for the AI, not an auth credential. Browser public access uses the matching publicKey + aiAgentDeploymentId pair, or the deployment ID alone for intentional guest mode. See Recipes § Logged-in user personalization.

How do I integrate with my analytics (GA / Segment / Mixpanel)?#

One-line pre-boot hook forwards every event:

html
<script>
  window.HelpAIHooks = window.HelpAIHooks || [];
  window.HelpAIHooks.push([
    '*',
    '*',
    (inst, event, data) => {
      analytics.track(`chat_${event}`, { widget: inst.widgetId, data });
    },
  ]);
</script>

Full examples: Recipes § Analytics forwarding.

How do I capture errors in Sentry / Datadog?#

ts
import { hook } from '@helpai/elements';

hook('*', 'error', (inst, _event, err) => {
  Sentry.captureException(err, { tags: { widget: inst.widgetId } });
});

Can I read the chat transcript server-side?#

Yes — our REST API exposes per-visitor / per-chat endpoints. Contact support for the API spec. Client-side, build your own log:

ts
const transcript = [];
chat.on('message', (m) => transcript.push({ ...m, at: Date.now() }));

How do I send the user a pre-filled first message?#

Configure welcome suggestion chips in your Help AI dashboard. Clicking a chip fills the composer with its text to edit before sending (or set behavior.autoSendSuggestions: true to send on tap). This is the intended pattern for "conversation starter" UX.

How do I trigger chat from a specific user action (e.g., after clicking a CTA)?#

ts
const chat = init({ publicKey: '...', aiAgentDeploymentId: '01900000-0000-7000-8000-000000000000' });

document.querySelector('#pricing-cta').addEventListener('click', () => {
  chat.open();
});

Behavior#

Why does the widget open automatically sometimes?#

When you set behavior.startMinimized: false explicitly. Otherwise it defaults to closed, and remembers the user's last open/close state across reloads.

Why does the panel restore from fullscreen when I reload?#

User's last size tier is remembered. If they closed while in fullscreen, it reopens in fullscreen. If they want to reset, clicking "New conversation" resets the layout too (or they can click the ⛶ button to exit fullscreen).

Why doesn't the widget show on Safari private mode?#

It does — but localStorage might be ephemeral, meaning chat history disappears when the tab closes. Everything else works.

Why do I see the "What can you do?" suggestion only sometimes?#

Suggestion chips are server-configured per deployment. The backend decides what to show based on:

  • New conversation — typically "What can you do?", "Show me pricing", etc.
  • Resumed chat — typically "Continue where we left off" or nothing.

If you're seeing unexpected ones, check your deployment's "Welcome → Suggestions" config in the dashboard.

Why does expanding the panel not work on mobile?#

The automatic tier uses fullscreen below 640 px, normal from 640–899 px, and expanded from 900 px by default. To change the desktop breakpoint:

ts
init({ presentation: { size: { autoSizeBreakpoint: 1200 } } }); // desktop expands at 1200px+

Why does my custom SVG icon render blank?#

Probably malformed SVG. The widget parses icons via DOMParser — verify yours is valid SVG 2.x. Use <path fill="currentColor"> for theming to work.

Why does Enter send when I'm composing CJK (Japanese/Chinese/Korean)?#

It shouldn't — the widget checks isComposing. If it's still happening, report a bug. Workaround: use Shift+Enter for a newline.


Billing & plans#

Does the widget consume API credits?#

Yes — every message sent to the AI uses your Help AI API credits. See help.ai/pricing (opens another site).

How do I cap spend per visitor?#

In your Help AI dashboard: Deployment → Limits → Per-visitor cap. When a visitor hits the cap, the widget shows "This conversation is closed. Start a new conversation?" (via canContinue: false).

What happens if my account runs out of credits?#

The widget still renders; users see an error when they try to send. The error event fires with the details. Configure a fallback UX:

ts
init({
  onError: (err) => {
    // Show a message or fall back to email form
    showFallbackContactForm();
  },
});

Versioning#

How do I know what version I'm running?#

js
console.log(window.HelpAI?.version);
// Or:
import { version } from '@helpai/elements';
console.log(version);

How do I pin to a specific version?#

html
<script src="https://cdn.help.ai/v1.2.0/elements.js" defer></script>

Or v1 for the latest v1.x.x (auto-patches but no major breaks).

When are breaking changes released?#

Only in major version bumps. Minor versions are additive. Patch versions are bug fixes. Semver throughout.

How do I upgrade?#

If you use the floating CDN URL, automatically. If pinned, update the version in your <script> tag. NPM users: npm update @helpai/elements.

Where's the changelog?#

github.com/help-ai/elements/releases (opens another site).


Support#

How do I contact support?#

How fast is support?#

  • Email: within 24 hours on weekdays.
  • Critical outages: tracked on status page in real-time.
  • Enterprise customers: SLA per contract.

Can I get a custom build?#

Yes — contact sales@help.ai for enterprise options. Custom brands, custom CDN, custom features are all on the table.

Still need help?

Ask the community