Docs

JavaScript Integration Guide

Add Heyo live chat to your JavaScript application. Works with vanilla JS, jQuery, and any library.

This guide shows you how to add Heyo to any JavaScript application, whether using vanilla JS, jQuery, or any library.

Installation

Method 1: HTML Script Tag

Add to your HTML:

<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <title>My App</title>
  <script src="https://heyo.so/embed/script" defer data-project-id="YOUR_PROJECT_ID"></script>
</head>
<body>
  <!-- Your app -->
</body>
</html>

Method 2: JavaScript SDK

Install via npm:

npm install @heyo.so/js

Then in your JavaScript:

// Use either import style
import HEYO from '@heyo.so/js'; // or: import { HEYO } from '@heyo.so/js'

// Initialize on page load
window.addEventListener('load', () => {
  HEYO.init({ projectId: 'YOUR_PROJECT_ID' });
});

Method 3: Dynamic Loading

Load the script dynamically:

(function() {
  const script = document.createElement('script');
  script.src = 'https://heyo.so/embed/script';
  script.defer = true;
  script.setAttribute('data-project-id', 'YOUR_PROJECT_ID');
  document.head.appendChild(script);
})();

Programmatic Control

Show, Hide, Toggle

// Show the chat widget
window.HEYO.show();

// Hide the chat widget
window.HEYO.hide();

// Toggle visibility
window.HEYO.toggle();

Custom Trigger Button

<button id="chat-button">Need Help?</button>

<script>
document.getElementById('chat-button').addEventListener('click', () => {
  window.HEYO?.show();
});
</script>

Wait for Widget to Load

window.addEventListener('load', () => {
  if (window.HEYO) {
    // Widget is ready
    console.log('Heyo is loaded');
  }
});

Advanced Usage

Pass User Data

window.addEventListener('load', () => {
  const user = getUserFromSession(); // Your auth logic
  
  if (user) {
    window.HEYO.init({
      projectId: 'YOUR_PROJECT_ID',
      user: {
        name: user.name,
        email: user.email,
        id: user.id
      }
    });
  }
});

Event Listeners

Track when chat opens:

// Custom event handling
document.addEventListener('DOMContentLoaded', () => {
  const observer = new MutationObserver((mutations) => {
    mutations.forEach((mutation) => {
      // Detect when chat widget changes
      if (mutation.target.id === 'heyo-widget-button') {
        console.log('Chat widget state changed');
      }
    });
  });
  
  observer.observe(document.body, {
    childList: true,
    subtree: true
  });
});

Integration with Single-Page Apps

For SPAs that change routes without page reload:

// Call on route change
function onRouteChange(route) {
  // Show/hide chat based on route
  if (route === '/checkout') {
    window.HEYO?.hide();
  } else {
    window.HEYO?.show();
  }
}

// Your router integration
router.on('routeChange', onRouteChange);

With jQuery

$(document).ready(function() {
  // Initialize Heyo
  if (window.HEYO) {
    window.HEYO.init({ projectId: 'YOUR_PROJECT_ID' });
  }
  
  // Custom button
  $('#chat-trigger').on('click', function(e) {
    e.preventDefault();
    window.HEYO?.show();
  });
});

With Async/Await

async function initializeChat() {
  // Wait for user data
  const user = await fetchUserData();
  
  // Initialize with user context
  window.HEYO?.init({
    projectId: 'YOUR_PROJECT_ID',
    user: {
      name: user.name,
      email: user.email
    }
  });
}

window.addEventListener('load', initializeChat);

Module Pattern

const Chat = (function() {
  let initialized = false;
  
  function init(projectId, userData) {
    if (initialized) return;
    
    window.HEYO?.init({
      projectId,
      user: userData
    });
    
    initialized = true;
  }
  
  function open() {
    window.HEYO?.show();
  }
  
  function close() {
    window.HEYO?.hide();
  }
  
  return {
    init,
    open,
    close
  };
})();

// Usage
Chat.init('YOUR_PROJECT_ID', { name: 'John', email: '[email protected]' });
Chat.open();

ES6 Class

class HeyoChat {
  constructor(projectId) {
    this.projectId = projectId;
    this.init();
  }
  
  init() {
    window.addEventListener('load', () => {
      window.HEYO?.init({ projectId: this.projectId });
    });
  }
  
  show() {
    window.HEYO?.show();
  }
  
  hide() {
    window.HEYO?.hide();
  }
  
  setUser(user) {
    window.HEYO?.init({
      projectId: this.projectId,
      user
    });
  }
}

// Usage
const chat = new HeyoChat('YOUR_PROJECT_ID');
chat.show();

TypeScript Support

Add type definitions:

declare global {
  interface Window {
    HEYO: {
      init: (config: { projectId: string; user?: any }) => void;
      show: () => void;
      hide: () => void;
      toggle: () => void;
    };
  }
}

export {};

Usage in TypeScript:

class ChatWidget {
  private projectId: string;
  
  constructor(projectId: string) {
    this.projectId = projectId;
    this.initialize();
  }
  
  private initialize(): void {
    window.addEventListener('load', () => {
      window.HEYO?.init({ projectId: this.projectId });
    });
  }
  
  public show(): void {
    window.HEYO?.show();
  }
  
  public hide(): void {
    window.HEYO?.hide();
  }
}

Best Practices

  • Load the script asynchronously (use defer attribute)
  • Wait for load event before calling HEYO methods
  • Use optional chaining (?.) when calling HEYO methods
  • Initialize once per page load
  • Handle cases where script fails to load gracefully
  • Pass user context for better support experience

Troubleshooting

HEYO is undefined

  • Ensure script has loaded before calling methods
  • Use window.addEventListener('load', ...)
  • Check for script loading errors in console

Methods not working

  • Verify Project ID is correct
  • Check browser console for errors
  • Ensure using correct method names

Multiple initializations

  • Only call init() once per page
  • Check you're not loading script multiple times

Next Steps