React Component
Install the widget as a React component with props, callbacks, and refs
To add the widget to a React app, install @wexio/messenger-widget-react. The component renders into a Shadow DOM portal, so the widget's styles never leak into your app and yours never leak into the widget.
Install
npm install @wexio/messenger-widget-react
# or
yarn add @wexio/messenger-widget-reactPeer dependencies are react >= 18 and react-dom >= 18.
Basic Usage
Render the component once, near the root of your app:
import { WexioWidget } from "@wexio/messenger-widget-react";
export default function App() {
return (
<>
<YourAppShell />
<WexioWidget publicKey="pk_live_..." />
</>
);
}Props
| Prop | Type | Purpose |
|---|---|---|
publicKey | string | Your widget's public key. Omit for demo mode. |
user | VisitorIdentity | A known-visitor proof - jwt, googleIdToken, or userId + userHash. Memoise it. See Authentication. |
config | InjectableWidgetConfig | A pre-resolved config; skips the bootstrap fetch. The widget still uses publicKey for the visitor handshake. |
theme | "light" | "dark" | "auto" | Force the widget theme from your page. Update it when your site switches theme and the widget follows. It wins over the dashboard default and the visitor's system setting. Omit it to let the widget decide. |
configOverride | Partial<WidgetConfig> | Presentation fields merged over the saved config, such as theme, greeting or features. Memoise it. See config reference. |
defaultOpen | boolean | Opens the panel on mount. After that the visitor can close it. |
open | boolean | Controlled open state. Keep it in sync from onOpen and onClose. Omit it for an uncontrolled widget. |
previewTab | { tab, nonce, article? } | Go to a tab or article and open the panel. A new nonce repeats the request. |
offset | { x?: number; y?: number } | Move the launcher away from its corner, in px. |
onResize | (size: { width: number; height: number }) => void | Fires whenever the panel's dimensions change. |
onOpen | () => void | Fires when the panel opens. |
onClose | () => void | Fires on every close: the header close button, the launcher and Escape. |
onMessageAction | (event) => void | Fires when a visitor clicks a quick reply on a welcome message. |
className | string | Applied to the outer host element. |
style | React.CSSProperties | Inline styles for the outer host element. |
Do not unmount the widget in onClose. It fires on every close, so the launcher would disappear each time. Keep the component mounted.
Identifying a Visitor
To identify a visitor, pass a memoised user prop. Changing it re-runs the handshake. Setting it to undefined logs the visitor out:
<WexioWidget
publicKey="pk_live_..."
user={{ jwt: serverSignedJwt, name: "Ada Lovelace", email: "ada@example.com" }}
onOpen={() => analytics.track("widget_opened")}
/>Build the user object outside render or wrap it in useMemo. The widget keys its handshake on the proof, so a fresh object literal every render can re-trigger work.
Without an npm Install (ESM CDN)
If you can't add a dependency, load the React bundle from the CDN with an import map:
<script type="importmap">
{
"imports": {
"react": "https://esm.sh/react@19",
"react-dom": "https://esm.sh/react-dom@19",
"react-dom/client": "https://esm.sh/react-dom@19/client",
"react/jsx-runtime":"https://esm.sh/react@19/jsx-runtime"
}
}
</script>
<div id="widget-mount"></div>
<script type="module">
import { createElement } from "react";
import { createRoot } from "react-dom/client";
import { WexioWidget } from "https://cdn.wexio.io/widget/widget-react.js";
const root = createRoot(document.getElementById("widget-mount"));
root.render(createElement(WexioWidget, { publicKey: "pk_live_..." }));
</script>Server-Side Rendering
The component returns null on the server and mounts its Shadow DOM portal on the first client effect, so it is safe in SSR frameworks like Next.js.
Try It Live
The examples repo has a runnable React (Vite) example. You can also configure the widget live in the Playground.
Related
- Authentication - produce a
VisitorIdentityproof. - Theming with config - pass a
themevia theconfigprop. - API reference - full prop list and types.
- Examples - runnable apps for every framework.