How to Use Custom Code for Widget
Custom Code allows adding custom JavaScript code that executes before widget initialization. This is useful for integration with third parties (Google Analytics, Intercom), modifying widget parameters, and creating global helper functions.
What is Custom Code?
Custom Code is JavaScript code that:
- Executes before initialization of Vue widget components
- Has access to
embed_state,kw_event(),kw_event_trigger() - Can modify widget parameters before initialization
- Supports Event Queue for handling events that occurred before code loading
Where to Configure Custom Code?
- Go to Settings → Bots → select bot → Widget
- Find the Custom Code section
- Enter your JavaScript code
- Save settings
Available Objects
In Custom Code, the following are available:
embed_state— widget state before initialization (can be modified)kw_event()— function to call eventskw_event_trigger()— function to trigger eventswindow— global browser object
Modifying Widget Parameters
Change widget parameters before initialization:
// Add parameters based on URL
embed_state.params_from_site = {
...embed_state.params_from_site,
page_url: window.location.href,
page_path: window.location.pathname,
user_agent: navigator.userAgent
};
// Change title based on page
if (window.location.pathname === '/products') {
embed_state.title = 'Product Questions';
embed_state.subtitle = 'Our consultants will help';
}
Google Analytics Integration
Track widget events in Google Analytics:
// Check for Google Analytics
if (window.gtag) {
// Track chat opening
window.addEventListener('widgetChatOpened', function() {
window.gtag('event', 'widget_chat_opened', {
event_category: 'Widget',
event_label: 'Chat Opened'
});
});
// Track chat closing
window.addEventListener('widgetChatClosed', function() {
window.gtag('event', 'widget_chat_closed', {
event_category: 'Widget',
event_label: 'Chat Closed'
});
});
}
Intercom Integration
Integrate widget with Intercom:
// Check for Intercom
if (window.Intercom) {
window.addEventListener('widgetChatOpened', function() {
window.Intercom('trackEvent', 'widget-chat-opened');
});
}
Using Event Queue
Handle events that occurred before Custom Code loading:
// Set event handler
window.__kw_custom_handler_ready = true;
// Process accumulated events
if (window.__kw_event_queue && window.__kw_event_queue.length > 0) {
window.__kw_event_queue.forEach(function(event) {
// Your event handling
console.log('Processing event:', event.event_name, event.event_data);
});
// Clear queue
window.__kw_event_queue = [];
}
Creating Helper Functions
Create global functions to simplify integration:
// Create helper function to open chat with product
window.openProductChat = function(productId, productName) {
kw_event('kwsetparamsfromsite', {
params_from_site: {
product_id: productId,
product_name: productName,
action: 'product_inquiry'
}
});
kw_event('command', {
title: 'Product Question',
subtitle: productName
});
kw_event('emitevent', {
event: 'alias',
alias: 'product-inquiry'
});
kw_event('openchat', 1);
};
// Usage on website
// <button onclick="openProductChat('12345', 'iPhone 15')">Ask about product</button>
Dynamic Configuration Based on URL
Configure widget depending on the current page:
// Analyze URL and change configuration
const path = window.location.pathname;
const searchParams = new URLSearchParams(window.location.search);
// Change title depending on page
if (path.startsWith('/products')) {
embed_state.title = 'Product Questions';
} else if (path.startsWith('/support')) {
embed_state.title = 'Technical Support';
} else {
embed_state.title = 'Help';
}
// Adding parameters from URL
if (searchParams.has('utm_source')) {
embed_state.params_from_site = {
...embed_state.params_from_site,
utm_source: searchParams.get('utm_source'),
utm_campaign: searchParams.get('utm_campaign')
};
}
Error Handling
Custom Code is wrapped in IIFE, so errors don't break the widget:
try {
// Your code
if (window.someExternalService) {
window.someExternalService.init();
}
} catch (error) {
console.error('Error in Custom Code:', error);
// Error won't affect widget operation
}
Limitations
- Code loads only if
widget_custom_code: trueandengine_urlis specified during initialization - Code executes synchronously before Vue component initialization
- If a parameter is already set in
kw('init', {...}), the value fromembed_statemay be overwritten - It's recommended to use unique names for global functions (with prefix)