Skip to content

SiteSage Ticket Widget

The sitesage-widget is a specialized Web Component designed to be embedded within ticket systems (like Zendesk, Salesforce, or custom internal tools). It provides agents with AI-generated reply suggestions and ticket insights.

Add the SiteSage script to your ticket system’s environment:

<script type="module" src="https://cdn.jsdelivr.net/npm/@sitesage/webcomponents@latest/dist/webcomponents.iife.js"></script>

The widget should be wrapped in a container that defines its dimensions.

<div class="sitesage-container">
<sitesage-widget
app_url="YOUR_APP_URL"
backend_url="YOUR_BACKEND_URL"
/>
</div>
<style>
.sitesage-container {
width: 600px;
height: 500px;
}
</style>

Unlike the sitesage-chat component, the widget requires active state management e.g. to sync with the ticket the agent is currently viewing.

Set the user property to identify the agent. The role must be set to agent for ticket system integrations.

const widget = document.querySelector("sitesage-widget");
widget.user = {
role: "agent",
name: "John Doe",
language: "da-DK" // Optional: UI localization
};

When an agent navigates between tickets, update the ticket property. The widget will automatically refresh its content without needing a full reload.

widget.ticket = {
message_id: 12345,
conversation_id: 67890
};

The widget communicates with the host system via standard DOM events.

When an agent clicks an AI-generated suggestion, the widget fires a texteditor:insert event. You should listen for this to inject the text into your system’s reply box.

widget.addEventListener("texteditor:insert", (event) => {
const textToInsert = event.detail.text;
// Your logic to add text to the ticket editor
console.log("AI Suggestion:", textToInsert);
});

To protect your Customer API Key, the widget does not perform authenticated requests directly from the browser. Instead, it emits a proxy:request event.

You must handle this event by routing the request through your own server.

widget.addEventListener("proxy:request", async (event) => {
const { request, respondWith, error } = event.detail;
try {
// Send the request details to your backend
const backendResponse = await fetch("/api/sitesage-proxy", {
method: "POST",
body: JSON.stringify(request)
});
const data = await backendResponse.json();
respondWith(new Response(JSON.stringify(data), { status: 200 }));
} catch (e) {
error("Proxy Communication Failure");
}
});

Your server receives the request, injects the secret API_KEY, and forwards it to SiteSage.

// Server-side Pseudo-code
function handleProxy(request) {
const API_KEY = CUSTOMER_SITESAGE_API_KEY;
// Replace the mustache placeholder with the actual key
const headers = request.headers.map(([key, value]) => [
key,
value.replace('{{sitesage_api_key}}', API_KEY)
]);
return fetch(request.url, {
method: request.method,
headers: headers,
body: request.body
});
}