@tidysupport/ui
v1.0.1
Published
TidySupport UI SDK - Support widget, session replay, and referral tracking
Downloads
221
Maintainers
Readme
@tidysupport/ui
- 💬 Chat widget — Embeddable support widget with a fully customizable UI
- 🎥 Session replay — Automatic rrweb-based recording, streamed to your dashboard
- 📊 Event tracking — Pageviews, custom events, and visitor presence
- ⚡ Real-time — WebSocket connection for live message notifications
- 🔐 Identity verification — HMAC-signed user identity to prevent spoofing
- 🐞 Bug reports — Programmatic bug report threads with context attached
- 📎 Attachments & screenshots — File and screen capture helpers built in
Installation
npm install @tidysupport/ui
# or
yarn add @tidysupport/ui
# or
pnpm add @tidysupport/uiQuick Start — Embed Script
The simplest integration: drop a <script> tag and the widget appears automatically.
<script
src="https://cdn.tidysupport.com/embeds/v1/support-widget.js"
data-publishable-key="pk_your_publishable_key"
async
defer
></script>Async queue (recommended)
For passing a signed user identity — or calling widget commands before the script loads — use the async queue pattern:
<!-- Step 1: initialize the queue -->
<script>
window.TidySupport = window.TidySupport || function() {
(window.TidySupport.q = window.TidySupport.q || []).push(arguments);
};
TidySupport('boot', {
publishableKey: 'pk_your_publishable_key',
email: '[email protected]',
name: 'Jane Doe',
signature: 'hmac_signed_on_backend', // from your backend
});
</script>
<!-- Step 2: load async -->
<script src="https://cdn.tidysupport.com/embeds/v1/support-widget.js" async defer></script>Commands queued before the script loads are replayed automatically once it initializes.
React Integration
Wrap your app with SupportProvider — the widget script is injected automatically.
import { SupportProvider } from '@tidysupport/ui/support/react';
export default function RootLayout({ children }) {
return (
<SupportProvider
publishableKey="pk_your_publishable_key"
identity={{
email: user.email,
name: user.name,
signature: user.tidysupportSignature, // HMAC from your backend
}}
>
{children}
</SupportProvider>
);
}useSupport hook
Access the widget API anywhere inside the provider:
import { useSupport } from '@tidysupport/ui/support/react';
function HelpButton() {
const support = useSupport();
return <button onClick={() => support.open()}>Contact support</button>;
}Available methods: open(), close(), show(), hide(), identify(), trackEvent(), trackPageview(), reportBug(), update(), shutdown().
useSupportAutoTracking
Automatically tracks pageviews on route changes:
import { useSupportAutoTracking } from '@tidysupport/ui/support/react';
function App() {
useSupportAutoTracking();
return <YourApp />;
}SupportProvider props
| Prop | Type | Default | Description |
| ---------------- | ------------------- | --------- | --------------------------------------- |
| publishableKey | string | required | Your pk_ publishable key |
| apiUrl | string | auto | Override API URL |
| widgetUrl | string | auto | Override widget iframe URL |
| align | 'left' \| 'right' | 'right' | Widget position |
| identity | object | — | { email, name, signature, visitorId } |
| autoMount | boolean | true | Inject embed script on mount |
Programmatic Client
Use SupportWidgetClient for full programmatic control — custom UIs, SSR, or headless integrations:
import { initSupportWidget } from '@tidysupport/ui/support';
const widget = initSupportWidget({
publishableKey: 'pk_your_publishable_key',
identity: {
email: '[email protected]',
signature: 'hmac_signed_on_backend',
},
});
await widget.mount();
await widget.updatePresence(true);SupportWidgetClient API
| Method | Description |
| -------------------------------- | ----------------------------------------------------- |
| mount() | Inject embed script and boot the widget |
| unmount() | Shut down and remove the widget |
| show() | Show the widget button |
| hide() | Hide the widget button |
| open() | Open the chat panel |
| close() | Close the chat panel |
| setIdentity(identity) | Update visitor email / name / signature |
| setVisitorId(id) | Manually set a visitor ID |
| trackPageview() | Track a pageview |
| trackEvent(event, properties?) | Track a custom event |
| bootstrap(input?) | Fetch widget bootstrap data (threads, settings, etc.) |
| sendMessage(payload, options?) | Send a message on behalf of the visitor |
| reportBug(input, options?) | Open a new thread pre-filled with a bug report |
| updatePresence(isOnline) | Update visitor online/offline presence |
| connectRealtime(options) | Subscribe to real-time events via WebSocket |
| getVisitorId() | Return the current visitor ID |
| getPublishableKey() | Return the configured publishable key |
Real-time events
const connection = widget.connectRealtime({
conversationId: 'conv_xxx',
onEvent: (event) => {
if (event.type === 'support.message.created') {
console.log('New message:', event.payload);
}
},
onConnectionChange: (connected) => {
console.log('WebSocket connected:', connected);
},
});
// Later
connection.setConversationId('conv_yyy');
connection.disconnect();Identity verification (HMAC signature)
Generate a signature on your backend and pass it as signature to prevent visitor spoofing:
// Backend (Node.js)
import crypto from 'crypto';
const signature = crypto
.createHmac('sha256', process.env.TIDYSUPPORT_SECRET_KEY!)
.update(user.email)
.digest('hex');Pass it to the widget:
// via programmatic client
widget.setIdentity({ email: user.email, signature });
// via React provider
<SupportProvider identity={{ email, signature }} />
// via embed script
TidySupport('boot', { publishableKey, email, signature });Use
@tidysupport/server'screateSupportWidgetSignature()helper if you're on Node.js.
Attachments & screenshots
import {
readSupportAttachment,
captureSupportScreenshot,
} from '@tidysupport/ui/support';
// Read a File from <input type="file">
const attachment = await readSupportAttachment(file);
// Prompt the user to share their screen
const screenshot = await captureSupportScreenshot();
await widget.sendMessage({
contentText: 'Here is my issue.',
attachments: [screenshot],
});window.TidySupport global API
| Method | Description |
| -------------------------------- | ------------------------ |
| boot(options?) | Initialize the widget |
| shutdown() | Tear down the widget |
| update(options?) | Update identity / config |
| identify(updates) | Update visitor identity |
| show() | Show the widget button |
| hide() | Hide the widget button |
| open(options?) | Open the chat panel |
| close() | Close the chat panel |
| trackEvent(event, properties?) | Track a custom event |
| trackPageview() | Track a pageview |
| reportBug(options) | Submit a bug report |
Documentation
Full guides, API reference, and framework-specific setup at tidysupport.com/docs
Not using npm?
If you're on a plain HTML site, Shopify, Webflow, WordPress, or any no-build stack — skip this package. Use the CDN embed script instead:
