Skip to main content

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 NEAR components. You can use it along the rest of approved VM tags to simplify your component development.

Using IFrames on NEAR 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.

paramdescription
messageit'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.

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

NEAR 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>
);
Was this page helpful?