Add the widget to a React or Next.js app
Mount the widget with one component, drive it with a hook, and get typed attributes in Vue and Svelte.
Last updated
The @helpai/elements package comes with a React kit: a component that adds the widget and a hook that drives it from any component. It works with server rendering, includes its TypeScript types, and needs React 18 or later.
1. Install the package#
npm install @helpai/elements2. Add the widget once, in your root layout#
// app/layout.tsx (Next.js App Router)
import { HelpAI } from '@helpai/elements/react';
type Props = { children: React.ReactNode };
export default function RootLayout({ children }: Props) {
return (
<html lang='en'>
<body>
{children}
<HelpAI
publicKey='agent_pk_...'
aiAgentDeploymentId='...'
theme='host'
/>
</body>
</html>
);
}Copy the public key and deployment ID from the deployment's Install tab. <HelpAI /> takes every widget option as a prop, the same as init(): theme, launcher, userToken, widgetId and more. It draws nothing itself: the widget appears once the page is running in the browser, a changed prop updates it in place, and removing the component removes the widget.
In the App Router, a server layout can only pass plain values. To use callback props such as onOpen or onMessage, render <HelpAI /> from a 'use client' component of your own.
3. Drive it from any component#
'use client';
import { useHelpAI } from '@helpai/elements/react';
export function PricingHelp() {
const { ask, open, state } = useHelpAI();
return (
<>
<button onClick={() => ask('Which plan fits us?')}>
Ask about plans
</button>
<button onClick={() => open({ to: 'help' })}>
Help ({state.unread} unread)
</button>
</>
);
}useHelpAI() returns state, ask, open, close, reset and track, and re-renders your component when the state changes. The calls work the same as in Control the widget with JavaScript. Before <HelpAI /> has mounted they do nothing; state.ready turns true once they act.
Import everything from @helpai/elements/react, types included, so every component talks to the same widget.
Signed-in users and a second widget#
- Signed-in users: pass a function that fetches your token as
userToken. Keep it the same function for the same user; removing the prop signs them out. See Verify signed-in users. - Two widgets: give each
<HelpAI widgetId='support' … />its own id, and read it withuseHelpAI('support'). See Run two widgets on one page.
Vue, Svelte and other frameworks#
Use the <web-ai-chat> element. Register it once:
import '@helpai/elements/web-component';With server rendering, such as Nuxt or SvelteKit, import it only in browser code: a Nuxt plugin whose file name ends in .client.ts, or onMount in SvelteKit, with await import('@helpai/elements/web-component'). The element can't be defined on the server.
Then add its types once, so your editor checks every attribute:
// Vue 3. For Svelte 5: /jsx/svelte. For React 19: /jsx/react
import type {} from '@helpai/elements/jsx/vue';Vue also needs web-ai-chat marked as a custom element. With Vite:
// vite.config.js
import vue from '@vitejs/plugin-vue';
export default {
plugins: [
vue({
template: {
compilerOptions: {
isCustomElement: (tag) => tag === 'web-ai-chat',
},
},
}),
],
};On the element, wait with await element.ready and listen with element.on(…). Listeners end when the element leaves the page.