Bookme Widget Documentation

A comprehensive JavaScript widget for embedding Bookme appointment scheduling into your website.

Table of Contents

Installation

Add the following script tag to your HTML page, preferably before the closing </body> tag:

<script src="https://bookme.botsplash.com/widget.js"></script>

Verification

After loading the script, the widget will be available as window.$bookme:

if (window.$bookme) {
  console.log('Bookme widget loaded successfully');
}

Quick Start

Basic Usage

// Load widget in a container element
window.$bookme.load('my-container', {
  account: 'your-account',
  agent: 'agent-name'
});

HTML Container

<div id="my-container"></div>
<script>
  window.$bookme.load('my-container', {
    account: 'your-account',
    agent: 'agent-name'
  });
</script>

API Reference

Methods

load(elementOrId, options)

Loads the Bookme widget into a specified container.

Parameters:

  • elementOrId (string Element) - Container element ID or DOM element
  • options (Object) - Configuration options

Returns: string - Container ID

Example:

const containerId = window.$bookme.load('booking-container', {
  account: 'botsplash',
  agent: 'demo2',
  meeting: 'consultation'
});

unload(elementOrId)

Removes the widget from the specified container.

Parameters:

  • elementOrId (string Element, optional) - Container to unload from

Example:

window.$bookme.unload('booking-container');
// or
window.$bookme.unload(); // unloads current widget

Configuration Options

Required Options

account (string, required)

Your Bookme account name.

window.$bookme.load('container', {
  account: 'your-account-name'
});

Agent or Team (one required)

You must specify either an agent or team, but not both.

agent (string)

Agent name for individual booking.

window.$bookme.load('container', {
  account: 'botsplash',
  agent: 'john-doe'
});
team (string)

Team name for team-based booking.

window.$bookme.load('container', {
  account: 'botsplash',
  team: 'support-team'
});

Optional Options

meeting (string, optional)

Specific meeting type slug.

window.$bookme.load('container', {
  account: 'botsplash',
  agent: 'demo2',
  meeting: 'discovery-call'
});

visitor (object, optional)

Pre-populate visitor information.

window.$bookme.load('container', {
  account: 'botsplash',
  agent: 'demo2',
  visitor: {
    firstName: 'John',
    lastName: 'Doe',
    email: 'john.doe@example.com',
    phoneNumber: '+1234567890',
    clientVisitorId: 'user-123',
    extendedAttributes: {
      company: 'ACME Corp',
      source: 'website',
      campaign: 'summer-2024',
      customField1: 'value1'
    }
  }
});
Visitor Fields
Field Type Description
firstName string Visitor’s first name
lastName string Visitor’s last name
email string Visitor’s email address
phoneNumber string Visitor’s phone number
clientVisitorId string Your internal visitor ID
extendedAttributes object Custom key-value pairs
Extended Attributes

The extendedAttributes object allows you to pass any custom data as key-value pairs:

extendedAttributes: {
  // Common use cases
  company: 'ACME Corporation',
  jobTitle: 'Marketing Manager',
  source: 'google-ads',
  campaign: 'holiday-sale-2024',
  referrer: 'partner-website',

  // Custom fields
  budget: '$10,000-$50,000',
  timeline: '3-6 months',
  region: 'North America',

  // Any other data
  customField1: 'value1',
  customField2: 'value2'
}

displayOptions (object, optional)

Customize widget appearance and behavior.

window.$bookme.load('container', {
  account: 'botsplash',
  agent: 'demo2',
  displayOptions: {
    width: '100%',
    height: '600px',
    maxWidth: '900px',
    hideMeetingInfo: true
  }
});
Display Options
Option Type Default Description
width string '100%' Widget width (CSS units)
height string '500px' Initial widget height (CSS units)
maxWidth string '800px' Maximum width constraint
customStyles string - Custom CSS rules injected into widget
hideMeetingInfo boolean false Hide meeting information section

Event Handling

Event Callbacks

onLoad(callback)

Triggered when the widget iframe loads successfully.

window.$bookme.onLoad(function(containerId, iframe) {
  console.log(`Widget loaded in container: ${containerId}`);
  console.log('Iframe element:', iframe);
});

onSizeChange(callback)

Triggered when the widget content size changes.

window.$bookme.onSizeChange(function(containerId, height, width) {
  console.log(`Size changed in ${containerId}: ${height}x${width}`);

  // Optionally trigger custom logic
  if (height > 800) {
    console.log('Widget is tall, consider scrolling to view');
  }
});

onNewMeetingCreated(callback)

Triggered when a meeting is successfully booked.

window.$bookme.onNewMeetingCreated(function(bookingData) {
  console.log('Meeting booked!', bookingData);

  // bookingData contains:
  // - message: Confirmation message
  // - bookme: { id, type, followupAt, status }
  // - visitor: { firstName, lastName, email, ... }

  // Custom actions after booking
  analytics.track('meeting_booked', {
    meetingId: bookingData.bookme.id,
    visitorEmail: bookingData.visitor.email
  });

  // Redirect or show success message
  window.location.href = '/booking-confirmation';
});

onExit(callback)

Triggered when the widget is about to be removed.

window.$bookme.onExit(function(containerId) {
  console.log(`Widget exiting from ${containerId}`);
  // Cleanup or save state
});

onPageNavigated(callback)

Triggered when the user navigates between pages within the widget.

window.$bookme.onPageNavigated(function(containerId, pageInfo) {
  console.log(`Page navigated in ${containerId}:`, pageInfo);

  // pageInfo contains:
  // - page: Current page path
  // - title: Page title
  // - url: Full URL
  // - timestamp: Navigation time

  // Track navigation for analytics
  analytics.track('widget_page_view', {
    page: pageInfo.page,
    url: pageInfo.url
  });
});

Setting Up Multiple Callbacks

// Set up all event handlers
window.$bookme.onLoad(handleLoad);
window.$bookme.onSizeChange(handleSizeChange);
window.$bookme.onNewMeetingCreated(handleBooking);
window.$bookme.onExit(handleExit);
window.$bookme.onPageNavigated(handleNavigation);

function handleLoad(containerId, iframe) {
  // Widget loaded logic
}

function handleSizeChange(containerId, height, width) {
  // Size change logic
}

function handleBooking(bookingData) {
  // Booking success logic
}

function handleExit(containerId) {
  // Exit cleanup logic
}

function handleNavigation(containerId, pageInfo) {
  // Navigation tracking logic
}

Examples

Basic Agent Booking

<div id="agent-booking"></div>
<script src="https://bookme.botsplash.com/widget.js"></script>
<script>
  window.$bookme.load('agent-booking', {
    account: 'botsplash',
    agent: 'demo2'
  });
</script>

Team Booking with Visitor Data

<div id="team-booking"></div>
<script>
  window.$bookme.load('team-booking', {
    account: 'botsplash',
    team: 'support',
    visitor: {
      firstName: 'Jane',
      lastName: 'Smith',
      email: 'jane.smith@company.com',
      phoneNumber: '+1987654321',
      extendedAttributes: {
        company: 'Tech Innovations Inc',
        source: 'website-contact-form',
        priority: 'high'
      }
    }
  });
</script>

Custom Styled Widget

<div id="custom-booking"></div>
<script>
  window.$bookme.load('custom-booking', {
    account: 'botsplash',
    agent: 'demo2',
    meeting: 'consultation',
    displayOptions: {
      width: '800px',
      height: '700px',
      customStyles: `
        .main-header {
          background: linear-gradient(135deg, #007bff 0%, #0056b3 100%) !important;
          color: white !important;
        }
        .booking-form {
          padding: 30px !important;
          border-radius: 12px !important;
          box-shadow: 0 4px 12px rgba(0,0,0,0.1) !important;
        }
        .timeslot-button {
          border-radius: 8px !important;
          transition: all 0.2s ease !important;
        }
      `,
      hideMeetingInfo: true
    }
  });
</script>

Mortgage/Insurance Agent Integration Example

// Pre-populate with client data from your CRM
const clientData = getClientFromCRM(); // Your function

window.$bookme.load('consultation-widget', {
  account: 'financial-services',
  agent: 'mortgage-advisor',
  meeting: 'mortgage-consultation',
  visitor: {
    firstName: clientData.firstName,
    lastName: clientData.lastName,
    email: clientData.email,
    phoneNumber: clientData.phone,
    extendedAttributes: {
      clientId: clientData.id,
      loanAmount: clientData.requestedAmount,
      propertyType: clientData.propertyType,
      creditScore: clientData.creditRange,
      employmentStatus: clientData.employment,
      referralSource: clientData.leadSource,
      urgency: clientData.timeframe,
      currentInsurance: clientData.hasInsurance
    }
  },
  displayOptions: {
    height: '650px',
    customStyles: `
      .main-header {
        background: #2c5aa0 !important;
        color: white !important;
      }
      .booking-form {
        font-family: 'Arial', sans-serif !important;
      }
    `
  }
});

// Handle successful booking
window.$bookme.onNewMeetingCreated(function(bookingData) {
  // Track in CRM system
  updateCRMRecord(clientData.id, {
    lastConsultationScheduled: bookingData.bookme.followupAt,
    meetingId: bookingData.bookme.id,
    status: 'consultation-scheduled'
  });

  // Send confirmation email
  sendClientConfirmation({
    clientEmail: clientData.email,
    meetingTime: bookingData.bookme.followupAt,
    agentName: bookingData.agentName
  });

  // Analytics tracking
  analytics.track('consultation_scheduled', {
    client_id: clientData.id,
    loan_amount: clientData.requestedAmount,
    meeting_id: bookingData.bookme.id
  });

  // Show success message
  showNotification('Your consultation has been scheduled! Check your email for confirmation.');
});

Responsive Widget

<style>
.responsive-booking-container {
  width: 100%;
  max-width: 900px;
  margin: 0 auto;
}

@media (max-width: 768px) {
  .mobile-booking {
    height: 600px !important;
  }
}

@media (max-width: 480px) {
  .mobile-booking {
    height: 500px !important;
  }
}
</style>

<div class="responsive-booking-container">
  <div id="responsive-booking"></div>
</div>

<script>
  const isMobile = window.innerWidth <= 768;

  window.$bookme.load('responsive-booking', {
    account: 'botsplash',
    agent: 'demo2',
    displayOptions: {
      width: '100%',
      height: isMobile ? '500px' : '700px'
    }
  });

  // Handle resize
  window.addEventListener('resize', function() {
    const newIsMobile = window.innerWidth <= 768;
    if (newIsMobile !== isMobile) {
      location.reload(); // Simple approach, or implement dynamic resize
    }
  });
</script>

Best Practices

1. Container Management

// ✅ Good - Use semantic container IDs
window.$bookme.load('main-booking-widget', options);

// ❌ Avoid - Generic IDs that might conflict
window.$bookme.load('div1', options);

2. Error Handling

try {
  window.$bookme.load('booking-container', {
    account: 'botsplash',
    agent: 'demo2'
  });
} catch (error) {
  console.error('Failed to load Bookme widget:', error);
  // Show fallback content or error message
  document.getElementById('booking-container').innerHTML =
    '<p>Booking widget temporarily unavailable. Please try again later.</p>';
}

Troubleshooting

Common Issues

Widget Not Loading

Symptoms: Container remains empty, no iframe appears.

Solutions:

// 1. Check if script is loaded
if (!window.$bookme) {
  console.error('Bookme script not loaded');
  // Ensure <script src="https://bookme.botsplash.com/widget.js"></script> is present
}

// 2. Verify container exists
const container = document.getElementById('your-container-id');
if (!container) {
  console.error('Container element not found');
}

// 3. Check for JavaScript errors in console
// 4. Verify account and agent/team names are correct

Size Issues

Symptoms: Widget appears too small or too large.

Solutions:

// Set explicit dimensions
window.$bookme.load('container', {
  account: 'botsplash',
  agent: 'demo2',
  displayOptions: {
    height: '600px',
    width: '100%',
    maxWidth: '800px'
  }
});

// Use CSS for additional control
iframe[data-bookme-iframe="true"] {
  min-height: 500px !important;
  max-height: 800px !important;
}

Events Not Firing

Symptoms: Callback functions not being called.

Solutions:

// Set up callbacks BEFORE loading the widget
window.$bookme.onLoad(function(containerId) {
  console.log('Widget loaded');
});

// Then load the widget
window.$bookme.load('container', options);

Browser Compatibility

The widget supports:

  • Chrome 60+
  • Firefox 55+
  • Safari 12+
  • Edge 79+

For older browsers, consider adding polyfills:

<!-- For older browsers -->
<script src="https://polyfill.io/v3/polyfill.min.js?features=es6"></script>
<script src="https://bookme.botsplash.com/widget.js"></script>

Support

For additional support:

  • Check browser console for error messages
  • Verify all required parameters are provided
  • Test with minimal configuration first
  • Email support@botsplash.com with specific error details

Version History

  • v1.0.0 - Initial release with basic iframe embedding
  • v1.1.0 - Added visitor data pre-population
  • v1.2.0 - Enhanced display options and event callbacks
  • v1.3.0 - Single iframe architecture with container switching
  • v1.4.0 - Custom styling system, enhanced timeslot UX, navigation tracking, bidirectional communication

Copyright © 2025, Rohi LLC. All Rights Reserved.