@sanela/webchat
v0.3.6
Published
Loader for the embeddable webchat widget. Customers paste one <script> tag pointing at the loader and the widget boots itself. Also publishes the ESM/CJS source so the loader can be re-bundled into a customer's own CDN if needed.
Maintainers
Readme
@sanela/webchat
The <script>-tag loader for the embeddable webchat widget.
Most sites don't need to install this. Customers paste one
<script>tag pointing at the dashboard's/widget.jsroute and that's it — no npm install required. This package exists for sites that want to self-host the loader on their own CDN (e.g., strict CSP rules forbid loading/widget.jsfrom a third-party origin).
Standard install (no npm — just a script tag)
<script>
window.cw =
window.cw ||
function () {
(cw.q = cw.q || []).push(arguments);
};
</script>
<script
async
src="https://your-dashboard.example.com/widget.js"
data-source-key="pk_..."
></script>
<script>
cw("identify", {
id: "user_42",
email: "[email protected]",
signature: "hmac-from-server",
timestamp: 1715692800000,
});
cw("context", { order_id: "ORD-12345", cart_total: 4990 });
</script>Self-hosted install (rare)
pnpm add @sanela/webchatThen bundle node_modules/@sanela/webchat/dist/loader.iife.global.js into your own CDN bundle. The dashboard's /widget.js route serves this IIFE with the deployment's Convex URL injected before it. If you self-host, provide that URL yourself via data-convex-url="https://your-convex.example.com" or window.__SANELA_WEBCHAT_CONVEX_URL__.
A note on Subresource Integrity (SRI)
The standard install above intentionally omits integrity="sha384-…" / crossorigin="anonymous": the loader is served from the same origin as your dashboard and gets a fresh hash on every deploy — pinning an SRI hash would force every customer site to update the snippet on each release.
If you self-host the loader (the section above) or load /widget.js from a third-party CDN, the trust model changes — that's the right time to compute an SRI hash for your built loader.iife.global.js, pin it via integrity="sha384-…" + crossorigin="anonymous", and rotate it whenever you publish a new build.
API
| Command | Args | Effect |
| ---------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| cw('open') | — | Open the panel |
| cw('close') | — | Close the panel (session and history kept) |
| cw('toggle') | — | Toggle the panel |
| cw('identify') | { id, email?, name?, signature?, timestamp?, customData? } | Identify user; merges anonymous + identified. signature requires timestamp (Date.now() at sign time). |
| cw('context') | object whose keys match the source's whitelist on the dashboard | Push business data the operator should see |
Calls made before the loader finishes downloading are queued and replayed when it's ready — that's what the window.cw = window.cw || … stub on the first line is for.
License
MIT
