Custom Components in Chat
You can inject custom interactive components (like video previews, loaders or buttons) directly inside your AI Agent chat. There are two ways to achieve this:
- Using frontend Callbacks — Add components dynamically via JavaScript callbacks when AI Agent sends data or triggers events.
- Using Tools/Actions - Return custom HTML components directly from a Function Node within your tools using the
_agent_custom_componentsparameter.
Method 1: Custom Components Using frontend Callbacks
This method allows you to inject custom HTML components dynamically in the chat when AI Agent sends structured data or triggers specific events.
Load AI Agent Script and Initialize
Add the AI Agent script to your webpage before the closing </body> tag and initialize it with tools and callbacks.
<script type="application/javascript">
(function(w,d,s,o,f,js,fjs){
w[o]=w[o]||function(){(w[o].q=w[o].q||[]).push(arguments);};
js=d.createElement(s);
fjs=d.getElementsByTagName(s)[0];
js.id=o;
js.src=f;
js.async=1;
js.referrerPolicy="origin";
fjs.parentNode.insertBefore(js,fjs);
})(window,document,"script","copilot",
"https://script.copilot.live/v1/copilot.min.js?tkn=YOUR_TOKEN_HERE");
copilot("init", {}, function() {
// Register tools (optional)
copilot.tools.add([
{
name: "open_cart",
description: "Opens user's cart",
handler: () => ({ success: true, message: "Cart opened" }),
},
]);
// Handle Navigate button clicks
copilot.callbacks.add({
name: "call_api",
handler: (val) => {
// call internal api with the value provided
},
});
// Handle Quick Replies
copilot.callbacks.add({
name: "send_message",
handler: (val) => {
copilot("event", "sendUserMessage", { value: val.value });
},
});
// Custom component handler
copilot.callbacks.add({
name: "tool:components",
handler: (data) => {
const customDiv = document.createElement("div");
customDiv.innerHTML = `
`;
return { id: "video-card", content: customDiv };
},
});
});
</script>
Adding Buttons to Custom Components
There are two ways to define or add buttons in your custom components:
Method 1: Using data-callback-type="instruction"
This is the simplest approach. Add buttons with data-callback-type="instruction" and they will automatically send responses back to the chat when clicked.
Example:
<!-- Button that triggers a chat instruction when clicked -->
<button
data-callback-type="instruction"
data-callback-name="quick_reply"
data-callback-args='{"value":"Sample action triggered"}'
>
Perform Action
</button>
<!-- Button to navigate the user to a specific URL -->
<button
data-callback-type="instruction"
data-callback-name="navigate"
data-callback-args='{"url":"https://example.com"}'
>
Navigate
</button>
Method 2: Register the callback handler
Register a callback function with the same name as the button’s data-callback-name attribute. This function will automatically execute when the button is clicked. For additional details, refer to the section above.
copilot("init", {}, function() {
// Register callback to handle button clicks
copilot.callbacks.add({
name: "custom_action",
handler: (args) => {
// args will contain: {"action":"process_order","orderId":"12345"}
console.log("Processing order:", args.orderId);
// Perform your custom logic here
// For example: call an API, update UI, etc.
fetch('/api/process-order', {
method: 'POST',
body: JSON.stringify({ orderId: args.orderId }),
headers: { 'Content-Type': 'application/json' }
})
.then(response => response.json())
.then(data => {
// Optionally send a message back to chat
copilot("event", "sendUserMessage", {
value: `Order ${args.orderId} processed successfully!`
});
});
},
});
});
Use data-callback-type="instruction" for simple actions like sending messages or navigating. Register custom callback handlers when you need to perform complex logic, API calls, or update your application state before responding to the user.
Method 2: Custom Components via Workflow
This method allows you to return custom HTML components directly from a Function Node in your workflow using the _agent_custom_components property.
Step 1: Add a Tool Node
Start with a Tool Node — for example, one that fetches data or performs a calculation. This Tool Node provides the data or context needed for your custom component.
Step 2: Add a Function Node After the Tool
Add a Function Node immediately after your Tool Node. Inside this Function Node, you'll create and return your custom HTML using _agent_custom_components. The Function Node processes the data from the Tool Node and formats it into an interactive HTML component that will be displayed in the chat.
Example Code
const _agent_custom_components = `
<div id="product-card" style="
max-width:480px;
margin:24px auto;
padding:20px;
background:#ffffff;
border:1px solid #e5e7eb;
border-radius:14px;
box-shadow:0 2px 6px rgba(0,0,0,0.05);
font-family:system-ui, sans-serif;
">
<h3 style="text-align:center;color:#0f172a;margin-bottom:12px;">🛒 Product Details</h3>
<div style="display:flex;align-items:center;gap:12px;margin-bottom:16px;">
<img
src="https://headsetsindia.com/wp-content/uploads/2020/06/evolve2_65b-1-750x750.jpg"
alt="Product image"
style="width:80px;height:80px;border-radius:8px;object-fit:cover;border:1px solid #d1d5db;"
/>
<div style="flex:1;">
<p style="margin:0;font-weight:600;color:#111827;">Wireless Headphones</p>
<p style="margin:2px 0 6px;color:#6b7280;font-size:14px;">Bluetooth 5.0, Noise Cancelling</p>
<p style="margin:0;color:#0d6efd;font-weight:600;">$59.99</p>
</div>
</div>
<div style="display:flex;flex-wrap:wrap;gap:10px;">
<!-- Add to Cart Button -->
<button
data-callback-type="instruction"
data-callback-name="quick_reply"
data-callback-args='{"value":"Added to cart"}'
style="flex:1;padding:8px;border:none;border-radius:8px;background:#198754;color:#fff;cursor:pointer;"
>
Add to Cart
</button>
<!-- Go to Checkout Button -->
<button
data-callback-type="instruction"
data-callback-name="navigate"
data-callback-args='{"url":"https://example.com/checkout"}'
style="flex:1;padding:8px;border:none;border-radius:8px;background:#0d6efd;color:#fff;cursor:pointer;"
>
Go to Checkout
</button>
<!-- View Details Button -->
<button
data-callback-type="instruction"
data-callback-name="navigate"
data-callback-args='{"url":"https://example.com/product"}'
style="flex:1;padding:8px;border:none;border-radius:8px;background:#6b7280;color:#fff;cursor:pointer;"
>
View Details
</button>
</div>
<div style="margin-top:14px;border:1px dashed #d1d5db;border-radius:8px;padding:10px;text-align:center;color:#374151;">
Status: <span id="status-value">Available in stock ✅</span>
</div>
</div>`;
return { _agent_custom_components };
Combine multiple buttons with different callback types to create richer, more dynamic user interactions directly inside your chat UI. For example, you could create a component with action buttons, navigation buttons, and status displays all working together to provide a complete interactive experience.