@recordari/support-widget
v0.2.0
Published
React support ticket panel for Salescaling multi-app support
Readme
@recordari/support-widget
React 18+ support panel for Salescaling (ESM, CJS, TypeScript). Peer dependencies: react, react-dom (≥18).
The npm package is a thin SDK (client, provider, loader). The provider loads the panel UI at runtime from the Salescaling CDN (https://assets.salescaling.com/support-widget/v1/widget.js by default) as a classic script and mounts it inside a Shadow DOM. UI updates ship on the CDN without redeploying your app.
Install
pnpm add @recordari/support-widgetQuick start
- Ask your Salescaling administrator to register your app (Support applications) and share the public client ID with your team and the signing secret with your backend only.
- Add a server route that returns a short-lived support token for the logged-in user (your backend signs it; the browser never sees the secret).
- Wire the widget:
import {
init,
SupportProvider,
SupportWidget,
useSupportWidget,
} from "@recordari/support-widget";
const client = init({
apiUrl: "https://api.salescaling.com",
clientId: "…",
originApp: "your-app",
user: { id: "…", email: "…", name: "…" },
tenant: { id: "…", name: "…" },
getUserToken: async () => {
const res = await fetch("/api/support-token");
if (!res.ok) throw new Error("Support token unavailable");
return (await res.json()).token;
},
});
export function App() {
return (
<SupportProvider client={client}>
<YourApp />
<SupportButton />
<SupportWidget theme="system" />
</SupportProvider>
);
}
function SupportButton() {
const { open } = useSupportWidget();
return <button onClick={open}>Abrir soporte</button>;
}Recreate client when the signed-in user or tenant changes. The package does not render a launcher button; create the trigger in your application and open the panel with useSupportWidget().open().
The provider injects the CDN script once and exposes loading and lifecycle state:
<SupportProvider
client={client}
onLoad={() => console.log("Support widget ready")}
onLoadFailed={(error) => console.error(error)}
onOpen={() => console.log("Support opened")}
onClose={() => console.log("Support closed")}
>
<App />
</SupportProvider>useSupportWidget() returns open, close, toggle, identify, isOpen, isLoading, and loadError.
Options
| Area | Notes |
| ----------------- | ---------------------------------------------------------------------------------------- |
| size | small | medium | large |
| theme | light | dark | system |
| palettes | Optional light/dark tokens; host CSS does not apply inside Shadow DOM |
| widgetBundleUrl | Optional pin to a specific bundle URL (immutable version or staging) |
| Hooks (SDK) | useSupportWidget, useSupportClient — control the panel and identify the current user |
For custom UIs without the default panel, call methods on the SupportClient returned by init() (tickets, createTicket, messages, etc.).
Types and defaults are exported from the package entry point.
Content Security Policy
Allow script loads from https://assets.salescaling.com (or your pinned widgetBundleUrl host). Your app must allow connect-src to the apiUrl configured in init.
Security
- Treat
clientIdas public configuration, not an auth secret. - Keep the signing secret on the server only (never
NEXT_PUBLIC_*). - Token format, claims, rotation, and scopes are defined by the Salescaling support API; follow the integration notes your administrator provides.
Salescaling web-platform contributors: README.internal.md (not published to npm).
