Skip to main content

Iframes

If your app is using iframes, you can add full support of the sos JS API within the iframe, without bundling it with the iframe code. But we recommend limiting the use of iframes inside your Applet to avoid performance hiccups.

warning

The signageOS Snippet and API works ONLY if the iframe is served from the display's internal storage (e.g. saved by sos.offline.cache.loadOrSaveFile()). If your iframe is served from a live URL - <iframe src="https://your-iframe-url"... the snippet and signageOS API will NOT work. This is a security limitation to prevent random site took advantage of the API and alter the display behavior. There is a simple way to save and load your iframe from the internal storage. Just make sure you are using full paths in your iframe for linking javascripts and css instead of the relative ones.

If your device cannot read a file stored in a local storage, such as html, you can try using an alternative method (instead of python) to zip the file when preparing the applet.

// applet
import sos from '@signageos/front-applet';

sos.onReady().then(async function () {
const contentElement = document.getElementById('index');
const iframeElement = document.getElementById('iframe');

const iframeUri =
sos.config.iframeUri ||
'https://raw.githubusercontent.com/signageos/applet-examples/master/examples/content-js-api/iframes/singlefile-applet/iframe.html';

const { filePath } = await sos.offline.cache.loadOrSaveFile('iframe.html', iframeUri);

contentElement.innerHTML = '';

iframeElement.src = filePath;
iframeElement.style.display = 'block';
});

This code will save an html page to the cache and creates a new iframe element with the saved filePath.

To inject the sos API into the iframe, add the snippet below to the iframe page, where the sos API is used:

<!-- iframe.html -->
<script type="text/javascript">
// sOS JS API loader !function()
{
(window.addEventListener('message', function (t) {
if (t.source === window.parent && 'hug.api_js_uri' === t.data.type) {
var e = t.data.uri;
if (!e) throw new Error('Front applet JS is not set.');
var a = document.createElement('script');
a.setAttribute('type', 'text/javascript'),
a.setAttribute('src', e),
(a.onload = a.onreadystatechange =
function () {
(this.readyState && 'loaded' != this.readyState && 'complete' != this.readyState) ||
((window.sos.apiJsUri = t.data.uri),
window.dispatchEvent(new Event('hug.loaded')),
window.dispatchEvent(new Event('sos.loaded')));
}),
document.head.appendChild(a);
}
}),
window.parent.postMessage({ type: 'hug_loader.ready' }, '*'))
}
();
</script>

The snippet will inject the sos API into the window object and fires sos.loaded event. When the event is fired, the sos API is ready to use.

// iframe.js
window.addEventListener('sos.loaded', async function () {
const contentElement = document.getElementById('index');
const videoArguments;

const videoUri = sos.config.videoUri || 'https://static.signageos.io/assets/video-test-1_e07fc21a7a72e3d33478243bd75d7743.mp4';
const { filePath } = sos.offline.cache.loadOrSaveFile('video.mp4', videoUri);

await sos.video.play(filePath, 0, 0, document.documentElement.clientWidth, document.documentElement.clientHeight);
});