DEV Community

Cover image for How to Build Responsive Cross-Origin iframe Embeds
GalleryDock
GalleryDock

Posted on

How to Build Responsive Cross-Origin iframe Embeds

Embedding an external web app with an iframe is easy until the content inside starts changing height.

A fixed height usually creates one of two problems: too much empty space or an unwanted scrollbar.

For cross-origin iframes, the parent page cannot simply read the height of the embedded document because of the browser's same-origin policy.

A clean solution is to combine ResizeObserver with postMessage.

Inside the embedded page

The embedded application measures its own height and sends it to the parent:

function sendHeight() {
  window.parent.postMessage(
    {
      type: "iframe-resize",
      height: document.documentElement.scrollHeight
    },
    "https://example.com"
  );
}

const observer = new ResizeObserver(sendHeight);

observer.observe(document.documentElement);

window.addEventListener("load", sendHeight);
Enter fullscreen mode Exit fullscreen mode

ResizeObserver is useful because the height can change after the initial page load.

For example:

  • images may load later
  • accordions may open
  • responsive layouts may change
  • dynamic content may be added
  • fonts may affect the layout

Instead of guessing a height, the iframe reports its actual size whenever something changes.

On the parent page

The parent listens for the message and updates the iframe:

const iframe = document.querySelector("#embedded-app");

window.addEventListener("message", (event) => {
  if (event.origin !== "https://embedded.example.com") {
    return;
  }

  if (event.data?.type !== "iframe-resize") {
    return;
  }

  const height = Number(event.data.height);

  if (!Number.isFinite(height) || height <= 0) {
    return;
  }

  iframe.style.height = `${height}px`;
});
Enter fullscreen mode Exit fullscreen mode

The iframe itself can stay simple:

<iframe
  id="embedded-app"
  src="https://embedded.example.com"
  style="width: 100%; border: 0;"
></iframe>
Enter fullscreen mode Exit fullscreen mode

Now the embedded content can grow or shrink without introducing an internal scrollbar.

Validate the origin

A common shortcut is:

window.parent.postMessage(data, "*");
Enter fullscreen mode Exit fullscreen mode

That works, but it is better to specify the expected origin whenever possible.

The receiving page should also validate event.origin.

Treat messages coming from an iframe like any other external input: verify where they came from before using the data.

The result

This pattern keeps responsibilities clean:

  • the embedded app knows its own content height
  • the parent controls the iframe element
  • postMessage connects both sides safely
  • ResizeObserver reacts to layout changes

It is a simple approach, but it solves one of the most common problems with responsive cross-origin embeds without relying on arbitrary fixed heights.

This article was created with AI assistance and reviewed for technical accuracy before publication.

Top comments (0)