console.log("widget opened")}
onClose={() => console.log("widget closed")}
/>
);
}
```
Mount it once at the app root:
```tsx
export default function App() {
return (
<>
>
);
}
```
Next.js note [#nextjs-note]
The component returns `null` on the server and mounts on the first client effect, so it's safe in the App Router or Pages Router. If you sign the JWT in a server component or route handler, pass it down as a prop (as `wexioJwt` above) — never expose your [shared secret](/docs/web-widget/create-widget#public-key-vs-shared-secret) to the client.
What to change [#what-to-change]
| Token | Replace with |
| ------------- | --------------------------------------------------------------------------------------------------------- |
| `pk_live_...` | Your [public key](/docs/web-widget/create-widget#public-key-vs-shared-secret). |
| `wexioJwt` | A [server-signed JWT](/docs/web-widget/authentication/jwt) — omit `user` entirely for anonymous visitors. |
Related [#related]
* [React component reference](/docs/web-widget/install/react) — full prop list and types.
* [Signed JWT](/docs/web-widget/authentication/jwt) — how to mint the token server-side.
# Example — React (ESM CDN) (/docs/web-widget/examples/react-esm)
Embed the React component inside any page **without an npm install** — the bundle is served from the same CDN as the loader and web component. React and React DOM come from the host page via an import map, so the widget's externalised peer deps resolve.
This mirrors the live demo at `https://cdn.wexio.io/widget/widget-react-demo.html`.
Full page [#full-page]
```html
Wexio Widget — React component (ESM CDN)
My website
— waiting for callbacks —
```
The live CDN demo imports the bundle by the relative path `/widget/widget-react.js` because it's served from the CDN origin. For your own site, import the **absolute** `https://cdn.wexio.io/widget/widget-react.js` (as above) so its code-split chunks resolve correctly.
What to change [#what-to-change]
| Token | Replace with |
| ------------- | ------------------------------------------------------------------------------ |
| `pk_live_...` | Your [public key](/docs/web-widget/create-widget#public-key-vs-shared-secret). |
Related [#related]
* [React component reference](/docs/web-widget/install/react) — full prop list.
* [React app (npm) example](/docs/web-widget/examples/react-app) — if you have a bundler.
# Example — Script Loader (/docs/web-widget/examples/script-loader)
The simplest embed: one `