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.src reloads the widget so the customer starts on a clean form.
  • Auto resize — The widget sends a wrenchflow:schedule:resize postMessage 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 message listener uses the exact origin returned by new 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.