How-to
Article MarkdownReport an error

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?

  1. Go to Settings → Bots → select bot → Widget
  2. Find the Custom Code section
  3. Enter your JavaScript code
  4. 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 events
  • kw_event_trigger() — function to trigger events
  • window — 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: true and engine_url is specified during initialization
  • Code executes synchronously before Vue component initialization
  • If a parameter is already set in kw('init', {...}), the value from embed_state may be overwritten
  • It's recommended to use unique names for global functions (with prefix)

Using your own AI agent?Install the open skill so your AI agent can work with current official ConnectiveOne documentation.Get the skillNeed support?Couldn’t find the answer or need help from the ConnectiveOne team? Create a request in Client Portal.Create a request