Using IFrames

To Share and +4 nLEARNs

Iframes

In this tutorial you’ll learn how to use the iframe VM tag and the Iframe resizer library, so you can embed external HTML or use custom DOM elements when building BOS components.
You can use it along the rest of approved VM tags to simplify your component development.

Using IFrames on BOS VM

Iframes can be used to embed external HTML or to use custom DOM
elements, for example canvas.

Properties

The iframe tag takes the following properties: className, style, src,
srcDoc, title, message, and onMessage. The iframe has a sandbox property
set to sandbox="allow-scripts", which only allows scripts.

::info

message and onMessage are used to communicate with this iframe
instance.

::

param description
message it’s passed to the iframe every time the deep equal is different, or the iframe is recreated. The message is passed using contentWindow.postMessage(message, "*") on the iframe.
onMessage(data) it’s called when the iframe passes a message to window.top. Only event.data is passed to the onMessage

Events

The VM exposes the following <iframe> events:

  • onLoad(): support for onLoad event without any event info

    <iframe onLoad={() => { console.log('iframe loaded') }}>
  • onResized(): support for onResized Iframe Resizer event with an object only containing the new width and height

    <iframe iframeResizer={{
      onResized: ({width, height}) => { console.log('iframe resized', width, height) },
    }}>

Example

The following example demonstrates how you can use an iframe to call
eval:

State.init({
  text: `"b" + "a" + +"a" + "a"`,
});

const code = `
<div>Expression: <pre id="exp" /></div>
<div>Results: <pre id="res" /></div>

<script>
    window.top.postMessage("loaded", "*");
    window.addEventListener("message", (event) => {
        const data = event.data
        document.getElementById("exp").innerHTML = JSON.stringify(data);
        try {
            const result = eval(data.exp);
            document.getElementById("res").innerHTML = result;
            event.source.postMessage(result, "*");
        } catch (e) {
            // ignore
        }
    }, false);
</script>
`;

return (
  <div>
    <input
      value={state.text || ""}
      onChange={(e) => State.update({ text: e.target.value })}
    />
    Iframes below
    <div className="d-flex">
      <iframe
        className="w-50 border"
        srcDoc={code}
        message={{ exp: state.text || "" }}
        onMessage={(res1) => State.update({ res1 })}
      />
      <iframe
        className="w-50 border"
        srcDoc={code}
        message={{ exp: (state.text || "") + " + ' banana'" }}
        onMessage={(res2) => State.update({ res2 })}
      />
    </div>
    Result:{" "}
    <pre>
      res1 = {JSON.stringify(state.res1)}
      res2 = {JSON.stringify(state.res2)}
    </pre>
  </div>
);

iframes

Iframe Resizer

Iframe Resizer is a critical library for rendering responsive iframes. This library automatically resizes the iframe to match the child content size to avoid scrollbars on the iframe itself.

::caution don’t forget

The child page rendered by the iframe must include this script in order for the resizing to work:

<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.6/iframeResizer.contentWindow.js"></script>
:::

::note

BOS VM uses the React flavor of this plugin.

::

Basic Example

You can use the Iframe resizer library like this:

return (
  <div>
    <iframe
      iframeResizer
      src="https://davidjbradshaw.com/iframe-resizer/example/frame.content.html"
    />
  </div>
);

If you need to pass in options to override the default behavior:

return (
  <div>
    <iframe
      iframeResizer={{ log: true }}
      src="https://davidjbradshaw.com/iframe-resizer/example/frame.content.html"
    />
  </div>
);
iframe resizer

::tip

You can check this example to see a complete component using Iframe Resizer.

::

srcDoc Example

An example of a valid srcDoc for a secure Iframe using iframeResizer:

const code = `
<script>
// ...your code...

// define message handler
const handleMessage = (m) => {
  console.log('received message', m)
  document.getElementById("messageText").innerHTML = m;
};

// finally, configure iframe resizer options before importing the script
window.iFrameResizer = {
    onMessage: handleMessage
  }
</script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/iframe-resizer/4.3.6/iframeResizer.contentWindow.js"></script>
<p id="messageText">loading...</p>
`;

return (
  <div>
    <iframe
      iframeResizer
      className="w-100"
      srcDoc={code}
      message="my message"
    />
  </div>
);
Generate comment with AI 2 nL
Scroll to Top
Report a bug👀