How to dynamically update Calendly widget URL and refresh display using JavaScript

I’m working on a webpage that needs to display different Calendly booking widgets based on user selection. When someone picks a different person from a dropdown or list, I want to update the calendar widget to show that person’s availability.

My current setup uses this HTML structure:

<div class="booking-widget-container" data-calendly-url="user_booking_link_here"></div>

The problem I’m facing is that after I change the data-calendly-url attribute with JavaScript, the widget doesn’t refresh automatically. It still shows the old calendar from the previous selection.

What’s the proper way to modify the URL attribute and force the Calendly widget to re-render with the new booking link? Do I need to reinitialize the widget somehow or is there a specific method to call?

Calendly doesn’t track attribute changes after it loads initially. I ran into this exact issue and found that completely removing and recreating the widget element works way better than just clearing innerHTML.

function updateCalendlyWidget(newUrl) {
  const oldContainer = document.querySelector('.booking-widget-container');
  const newContainer = document.createElement('div');
  newContainer.className = 'booking-widget-container';
  newContainer.setAttribute('data-calendly-url', newUrl);
  
  oldContainer.parentNode.replaceChild(newContainer, oldContainer);
  
  Calendly.initInlineWidget({
    url: newUrl,
    parentElement: newContainer
  });
}

This stops any leftover event listeners or cached data from messing with the new widget. I’ve seen clearing innerHTML leave behind Calendly’s internal references, which causes display problems. Replacing the entire DOM element gives you a clean slate every time.

Yeah, Calendly widgets don’t auto-refresh when you change the data attribute. You’ve got to destroy the old one and make a new one.

Here’s what works:

// Clear the existing widget first
const container = document.querySelector('.booking-widget-container');
container.innerHTML = '';

// Update the URL attribute
container.setAttribute('data-calendly-url', newBookingUrl);

// Reinitialize the widget
Calendly.initInlineWidget({
  url: newBookingUrl,
  parentElement: container
});

I’ve done this before - this method always works. Just clear the container completely before reinitializing.

Make sure you’ve got Calendly’s widget.js loaded first. Without it, initInlineWidget won’t exist.

If you’re switching widgets a lot, throw in a loading state so users don’t click around while it loads.