How to integrate the WrenchFlow Scheduling widget with my business' website
Let customers book appointments directly on your website. The scheduling widget is a lightweight iframe you can drop into any page.
Overview
Every WrenchFlow tenant has a unique scheduling URL:
https://<tenant-slug>.app.wrenchflow.com/scheduling/
Embed this URL in an <iframe> on your site. The widget loads
your shop's branding, services, and availability rules — customers pick a time
without ever leaving your page.
Basic embed
The simplest approach is a fixed iframe:
<iframe
src="https://demo.app.wrenchflow.com/scheduling/"
title="Book an appointment"
width="100%"
height="640"
style="border:0;"
allow="clipboard-write"
loading="lazy">
</iframe>
Modal / popup embed
Most shops prefer a "Book an Appointment" button that opens the scheduler in a modal so it does not take up space on the page. Here is a complete, minimal example:
<!-- Trigger button -->
<a href="#" class="btn-book" id="open-booking">Book an Appointment</a>
<!-- Modal markup -->
<div class="booking-modal" id="booking-modal" role="dialog" aria-modal="true" aria-label="Book an appointment" hidden>
<div class="booking-overlay" id="booking-overlay"></div>
<div class="booking-dialog">
<button class="booking-close" id="booking-close" aria-label="Close">×</button>
<div class="booking-header">
<h2>Book an Appointment</h2>
<p>Powered by WrenchFlow</p>
</div>
<div class="booking-frame-wrap">
<iframe
id="booking-iframe"
src="https://demo.app.wrenchflow.com/scheduling/"
title="Book an appointment"
loading="lazy"
allow="clipboard-write">
</iframe>
</div>
</div>
</div>
And the JavaScript to open, close, and resize the iframe:
(function () {
var modal = document.getElementById('booking-modal');
var iframe = document.getElementById('booking-iframe');
var overlay = document.getElementById('booking-overlay');
var closeBtn = document.getElementById('booking-close');
function openModal() {
modal.hidden = false;
document.body.style.overflow = 'hidden';
// Reset iframe to force a fresh state each time it opens
iframe.src = iframe.src;
}
function closeModal() {
modal.hidden = true;
document.body.style.overflow = '';
}
document.getElementById('open-booking').addEventListener('click', function (e) {
e.preventDefault();
openModal();
});
closeBtn.addEventListener('click', closeModal);
overlay.addEventListener('click', closeModal);
document.addEventListener('keydown', function (e) {
if (e.key === 'Escape' && !modal.hidden) closeModal();
});
// Listen for resize messages from the widget
var widgetOrigin = new URL(iframe.src, window.location.href).origin;
window.addEventListener('message', function (event) {
if (event.origin !== widgetOrigin) return;
var data = event.data || {};
if (data.type === "wrenchflow:schedule:resize" && typeof data.height === "number") {
iframe.style.height = Math.max(640, data.height) + 'px';
}
});
})();
What the script does
- Open & close — Clicking the button shows the modal. Clicking the overlay, the close button, or pressing Esc hides it.
- Fresh state — Each time the modal opens,
iframe.src = iframe.srcreloads the widget so the customer starts on a clean form. - Auto resize — The widget sends a
wrenchflow:schedule:resizepostMessage when its content height changes. The parent updates the iframe height so there are no internal scrollbars.
Live example
See a fully-styled version of this integration on our demo shop page. It shows the modal flowing inside a realistic auto-shop website with header, hero, and services sections.
Requirements
- Your shop must be active on WrenchFlow (the scheduling URL will 404 otherwise).
- The page that embeds the iframe must be served over
https://so that modern browsers allow clipboard-write inside the iframe. - No API key or back-end code is required — this is a pure front-end embed.
Troubleshooting
- Widget shows a blank box
- Check that your tenant slug is correct.
- Height does not adjust
- Make sure the
messagelistener uses the exact origin returned bynew URL(iframe.src).origin. A wildcard (*) works for testing but should be restricted in production. - Copy-paste does not work inside the widget
- Add
allow="clipboard-write"to the iframe tag.
Need help?
If you run into issues, email us and we will help you get the widget running.