← Glossary

Iframe widget

An iframe widget is a self-contained web component delivered over HTTPS and rendered inside another page via an `<iframe>` element. The iframe isolates the widget's HTML, CSS, and JavaScript from the host page — they share no styles, no global variables, and no permissions beyond explicit postMessage communication. Iframe widgets are the dominant embed format on the modern web because they work in essentially any CMS, note-taking app, or content platform that accepts HTML or a URL.

Why iframes instead of web components or scripts?

Three reasons. (1) Security: the host page can't access the widget's DOM, and vice versa — protecting both parties from XSS. (2) Compatibility: every major platform (Notion, Obsidian, WordPress, Ghost, Substack) supports iframes; support for web components is inconsistent. (3) Versioning: the widget author can update the iframe's content without breaking any host page, because the host only knows the URL.

What are the constraints of iframe widgets?

Iframes have fixed dimensions unless the host supports dynamic resizing (Notion does, most don't). They can't directly access clipboard, camera, or storage in the host domain. Cross-origin restrictions apply — scripts inside the iframe can't read the parent page's content. Authentication flows inside an iframe often need a popup rather than an in-frame redirect.

How does WidgetCraft handle iframe sizing?

Every widget emits a `postMessage({ type: 'wc-height', height: N })` beacon on resize, which host platforms like Notion pick up and use to fit the iframe. Hosts that don't support the beacon fall back to a sensible default height attribute on the iframe tag. The contract is documented at contracts/widget-surfaces.md in the WidgetCraft repo.