The TidySupport widget adds a live chat interface to your website. Visitors can start conversations, receive AI-powered responses, and reach your support team directly. The widget supports authenticated and anonymous visitors, file attachments, email collection, and full customization.
Add this script tag to your website, just before the closing </body> tag. Replace the publishable key with your own from Settings > Integrations > API in your dashboard.
<script
src="https://api.tidysupport.com/embeds/v1/support-widget.js"
data-publishable-key="pk_live_YOUR_KEY_HERE"
async
defer
></script>That's it. The widget will appear as a chat button in the bottom-right corner of your page.
Configure the widget using data-* attributes on the script tag:
Example with pre-filled user data
<script
src="https://api.tidysupport.com/embeds/v1/support-widget.js"
data-publishable-key="pk_live_YOUR_KEY_HERE"
data-user-email="jane@example.com"
data-user-name="Jane Doe"
data-align="right"
async
defer
></script>For more control, use the JavaScript API instead of (or in addition to) data attributes. You can queue commands before the script loads.
Queue pattern (recommended)
<script>
// Initialize the command queue before the widget script loads
window.TidySupport = window.TidySupport || function() {
(window.TidySupport.q = window.TidySupport.q || []).push(arguments);
};
window.TidySupport.q = window.TidySupport.q || [];
// Queue commands — these run after the widget loads
window.TidySupport('boot', {
publishableKey: 'pk_live_YOUR_KEY_HERE',
email: 'jane@example.com',
name: 'Jane Doe'
});
</script>
<!-- Load the widget script -->
<script
src="https://api.tidysupport.com/embeds/v1/support-widget.js"
async
defer
></script>Available commands
Command examples
// Open the chat panel
window.TidySupport('open');
// Open with a pre-filled message
window.TidySupport('open', {
message: 'I need help with billing',
autoSend: false
});
// Update visitor identity (e.g., after login)
window.TidySupport('identify', {
email: 'jane@example.com',
name: 'Jane Doe'
});
// Hide the widget on specific pages
window.TidySupport('hide');
// Track a custom event
window.TidySupport('trackEvent', 'plan_upgraded', {
plan: 'pro',
amount: 29
});
// Remove the widget completely
window.TidySupport('shutdown');Identity verification uses HMAC-SHA256 signatures to securely associate widget sessions with known contacts. This prevents impersonation and ensures conversation history is linked to the correct customer.
Important: Generate signatures on your server, never in client-side code. Your signing secret must stay private.
Step 1: Generate the signature on your server
const crypto = require('crypto');
function generateWidgetSignature(signingSecret, visitorId, email) {
const payload = visitorId + ':' + (email || '').toLowerCase();
return crypto
.createHmac('sha256', signingSecret)
.update(payload)
.digest('hex');
}
// Example usage in an Express endpoint
app.get('/api/widget-signature', (req, res) => {
const signature = generateWidgetSignature(
process.env.TIDYSUPPORT_SIGNING_SECRET,
req.query.visitorId,
req.user.email
);
res.json({ signature });
});Step 2: Pass the signature to the widget
<script>
window.TidySupport = window.TidySupport || function() {
(window.TidySupport.q = window.TidySupport.q || []).push(arguments);
};
window.TidySupport.q = window.TidySupport.q || [];
// Fetch signature from your backend
fetch('/api/widget-signature?visitorId=vis_abc123')
.then(res => res.json())
.then(({ signature }) => {
window.TidySupport('boot', {
publishableKey: 'pk_live_YOUR_KEY_HERE',
visitorId: 'vis_abc123',
email: 'jane@example.com',
name: 'Jane Doe',
signature: signature
});
});
</script>
<script
src="https://api.tidysupport.com/embeds/v1/support-widget.js"
async
defer
></script>Tip: You can find your signing secret in Settings > Widget > Identity Verification in your dashboard. The signature format is HMAC-SHA256(signingSecret, visitorId:email).
For React, Next.js, or other single-page applications, install the SDK package and initialize programmatically.
Install the package
npm install @tidysupport/uiInitialize in your app
import { useEffect } from 'react';
import { initSupportWidget } from '@tidysupport/ui';
function App() {
useEffect(() => {
const client = initSupportWidget({
publishableKey: 'pk_live_YOUR_KEY_HERE',
identity: {
email: user.email,
name: user.name,
signature: userSignature, // from your backend
},
});
client.mount();
return () => {
client.unmount();
};
}, []);
return <div>{/* Your app */}</div>;
}Customize the widget appearance from Settings > Widget in your dashboard. Available options include:
Widget not appearing
pk_async and deferIdentity verification failing
visitorId:email (lowercase email)visitorId must be passed to both your signing endpoint and the widget boot commandConversations not linking to contacts
data-user-email attribute or use identify to associate the widget session with a known contact