
An embeddable widget is a guest on somebody else's website. It does not control the CSS reset, JavaScript framework, cookie banner, router, or performance budget. That is why the host-side loader stays small. It should add the chat entry point and get out of the way.
Only the trigger belongs on the host page
The loader creates the trigger button, applies minimal styles, fetches configuration, and opens an iframe for the chat UI. The conversation interface stays inside the iframe. That keeps message rendering, forms, uploads, search, reactions, and real-time logic away from the customer's DOM. Without that boundary, every customer website becomes a different integration bug.
Duplicate installs happen
Real sites are messy. A script can be added directly and again through a tag manager. A marketing test can load it twice. A single-page app can rerun an integration block after navigation. Convor exposes a singleton API and cleanup path so a second initialization does not create a second widget fighting for the same corner.
Branding fields still need validation
The widget accepts settings such as primary color, border radius, position, and bubble style. Values that become CSS are checked first. If a value is invalid, the loader falls back to a safe default. This is a small piece of code, but it matters. A dashboard setting should style the widget, not gain the power to inject arbitrary CSS into a customer's page.
postMessage is a protocol
The host page and iframe talk through postMessage. They use it for close events, unread counts, proactive messages, and page changes. The receiver checks origin and message source before acting. This is especially important for route tracking: the iframe needs the host URL, but random frames on the page should not be able to fake it.
The best loader is uneventful. It appears, opens, reconnects, cleans up after itself, and does not make the website owner think about it again.
Get new posts in your inbox
No spam. Unsubscribe anytime.
