Symphony Apps Development logo — teal interlocking S monogram beside the studio wordmark
All writing

Build note: a booking widget that had to work embedded

The hard part of an embeddable widget is not the widget. It is behaving inside a host page you do not control and cannot test exhaustively.

Category
Case notes
Reading time
6 min
Published
03 Jun 2026
Topics
Case study, Engineering, Product

A client asked for a booking widget their customers could drop into their own websites with a single script tag. The brief was short. The constraint underneath it was not.

You do not control the host page

Once a widget ships as an embed, it runs alongside CSS it did not write, on pages with unknown load order, sometimes inside other people's iframes, occasionally next to another copy of jQuery from 2014. Every assumption we would normally make about the page is gone.

What we isolated and how

  • Styles — everything ships inside a shadow root, so host page CSS cannot leak in and our styles cannot leak out.
  • Global state — no reliance on window-level variables the host page might also be using.
  • Script loading order — the widget initialises defensively and waits for its own dependencies rather than assuming the page loaded in the order we expect.
  • Failure visibility — if the widget fails to load, it fails silently to the host page's console, not to the customer's checkout flow.

The performance budget was the actual spec

The client's customers were paying to embed something that would not slow their own site down. We set a hard budget — under 40kb gzipped, one network request, no blocking script tag — and treated any feature request that broke the budget as a feature that needed a different shape, not a budget that needed relaxing.

An embeddable product's real user is the host site's engineer, deciding whether to trust your script tag. Win that decision or nothing else matters.

Testing against pages we do not own

We built a small set of deliberately hostile test pages — one with aggressive global CSS resets, one with a conflicting script loaded first, one inside a nested iframe — and ran the widget against all of them on every release. This caught more real bugs than testing against our own clean demo page ever did.

What shipped

The widget went live across several dozen customer sites in the first month with no reported style conflicts, which was the metric that mattered to the client far more than any feature count.

Tell us what you’re trying to ship

A first call is thirty minutes and costs nothing. Bring the problem, not a spec — working out what to build is the part we are good at.

Or email office@symphonyapps.ro. We reply within one business day, in English or Romanian.