Windows
Overview
Available since io.Connect Browser 4.5
The @interopio/iframes-api library provides a convenient way to open io.Connect apps in <iframe> elements.
The IFrames API is accessible via the io.iframes object.
Settings for IFrame Apps
You can use the iframePermissionsPolicy and the iframeSandbox properties of the details object in app definitions to provide settings for the allow and the sandbox attributes of the <iframe> elements in which the apps will be opened. These settings are valid for apps opened in standalone <iframe> elements via the IFrames API as well as for apps opened in <iframe> elements within a Workspace by the io.Connect platform.
The following example demonstrates how to define an app with settings for the allow and the sandbox attributes of the <iframe> element in which it will be opened:
import IOBrowserPlatform from "@interopio/browser-platform";
const config = {
licenseKey: "my-license-key",
applications: {
local: [
{
name: "my-app",
type: "window",
title: "My App",
details: {
url: "https://my-domain.com/my-app",
iframePermissionsPolicy: {
flags: "geolocation 'self' https://a.example.com https://b.example.com; fullscreen 'none'"
},
iframeSandbox: {
flags: "allow-scripts allow-same-origin"
}
}
}
]
}
};
const { io } = await IOBrowserPlatform(config);Enabling IFrames
To use the IFrames API in your interop-enabled apps, install the @interopio/iframes-api library in your project and reference it in your app. Depending on whether you want to use the IFrames API in your Main app, or in a Browser Client app, see the respective initialization examples in the following sections.
Main App
Install the necessary packages:
npm install @interopio/browser-platform @interopio/iframes-apiInitialize the @interopio/browser-platform library and enable the IFrames API by passing the IOIFrames() factory function to the libraries array of the browser configuration object:
import IOBrowserPlatform from "@interopio/browser-platform";
import IOIFrames from "@interopio/iframes-api";
const config = {
licenseKey: "my-license-key",
browser: {
libraries: [IOIFrames]
}
};
const { io } = await IOBrowserPlatform(config);
// Now you can access the IFrames API via `io.iframes`.Browser Clients
To enable the IFrames API in your Browser Client apps, install the @interopio/browser and @interopio/iframes-api libraries and initialize the @interopio/browser library by passing the IOIFrames() factory function in the configuration object. When IOBrowser() resolves, the IFrames API will be accessible via the iframes property of the returned object - e.g., io.iframes. The following examples demonstrate how to enable the IFrames API in JavaScript, React, and Angular apps.
JavaScript
Install the necessary packages:
npm install @interopio/browser @interopio/iframes-apiInitialize the @interopio/browser library and pass the IOIFrames() factory function to the libraries array of the configuration object:
import IOBrowser from "@interopio/browser";
import IOIFrames from "@interopio/iframes-api";
const config = {
libraries: [IOIFrames]
};
const io = await IOBrowser(config);
// Now you can access the IFrames API via `io.iframes`.By default, the IOBrowser() and IOIFrames() factory functions are injected in the global window object.
React
Install the necessary packages:
npm install @interopio/react-hooks @interopio/iframes-apiInitialize the @interopio/react-hooks library in one of the following ways and pass the IOIFrames() factory function to the libraries array of the configuration object for initializing the library.
- using the
<IOConnectProvider />component:
import { createRoot } from "react-dom/client";
import { IOConnectProvider } from "@interopio/react-hooks";
import IOBrowser from "@interopio/browser";
import IOIFrames from "@interopio/iframes-api";
const settings = {
browser: {
factory: IOBrowser,
config: {
libraries: [IOIFrames]
}
}
};
const domElement = document.getElementById("root");
const root = createRoot(domElement);
root.render(
<IOConnectProvider fallback={<h2>Loading...</h2>} settings={settings}>
<App />
</IOConnectProvider>
);- using the
useIOConnectInit()hook:
import { useIOConnectInit } from "@interopio/react-hooks";
import IOBrowser from "@interopio/browser";
import IOIFrames from "@interopio/iframes-api";
const App = () => {
const settings = {
browser: {
factory: IOBrowser,
config: {
libraries: [IOIFrames]
}
}
};
const io = useIOConnectInit(settings);
return io ? <Main io={io} /> : <Loader />;
};
export default App;Angular
Install the necessary packages:
npm install @interopio/ng @interopio/iframes-apiInitialize the @interopio/ng library and pass the IOIFrames() factory function to the libraries array of the configuration object for initializing the library.
In app.config.ts of the Browser Client app:
import { ApplicationConfig } from "@angular/core";
import { provideIoConnect } from "@interopio/ng";
import IOBrowser, { IOConnectBrowser } from "@interopio/browser";
import IOIFrames from "@interopio/iframes-api";
const config: IOConnectBrowser.Config = {
libraries: [IOIFrames]
};
export const appConfig: ApplicationConfig = {
providers: [
provideIoConnect({
browser: {
factory: IOBrowser,
config
}
})
]
};ℹ️ For more details on initializing and configuring the
@interopio/nglibrary depending on whether you are using Angular standalone components or modules, see the Developers > Browser Client > Angular section.
Opening Apps in IFrames
To open an app in an <iframe> element within the current app instance, use the openApp() method and pass an OpenAppConfig object as an argument:
const container = document.getElementById("my-iframe-container");
const config = {
appName: "my-app",
container,
context: { ticker: "MSFT" },
iframeConfig: {
styles: {
width: "100%",
height: "100%",
border: "none"
}
}
};
const { id, iframe } = await io.iframes.openApp(config);If container property is omitted, the created <iframe> element will be appended to document.body.
The openApp() method resolves with an Instance object describing the started app.
⚠️ Note that if you provide a container element, it must be connected to the DOM - otherwise,
openApp()will throw an error. If the container element is moved (e.g., via drag and drop), this will lead to disconnecting and reconnecting the<iframe>element to the DOM. The app instance will continue to run in the<iframe>element, but it won't be able to reconnect to the platform, because it has already been removed from the platform state. If the container element is deleted without closing the app instance in the<iframe>, it will be removed from the lists of io.Connect app and window instances tracked by the platform only if it's interop-enabled. That's why it's recommended to always close the app instance running in the<iframe>when removing the container element.
Events
To handle close requests for apps opened in <iframe> elements within the current app instance, use the onCloseRequested() method and provide a callback function for handling the event:
const iframeContainers = {};
const handler = async (instance, confirmClose) => {
// Confirm to the platform that the `<iframe>` can be closed.
await confirmClose();
// Remove the `<iframe>` container with your custom logic.
};
const unsubscribe = io.iframes.onCloseRequested();ℹ️ The
onCloseRequested()method notifies only about close requests only for<iframe>elements that have been created inside the current app instance.
Example
The following is a complete example demonstrating how to open an app in an <iframe> element, keep track of the <iframe> container, and handle close requests for the app:
// Create a map to store `<iframe>` containers by ID.
const iframeContainers = {};
// Handler for close requests.
const handler = async (instance, confirmClose) => {
// Confirm to the platform that the `<iframe>` can be closed.
await confirmClose();
// Remove the `<iframe>` container.
iframeContainers[instance.id]?.remove();
delete iframeContainers[instance.id];
};
// This method will notify only about close requests for `<iframe>` elements that have been created inside the current app instance.
const unsubscribe = io.iframes.onCloseRequested(handler);
// Start the app.
const start = async () => {
// Create a container where the `<iframe>` will be visualized.
const createIFrameContainer = () => {
const container = document.createElement("div");
container.style.width = "400px";
container.style.height = "300px";
container.style.boxSizing = "border-box";
container.style.border = "1px solid orange";
document.body.appendChild(container);
return container;
}
const container = createIFrameContainer();
// Passing CSS classes and styles before opening the app instance in an `<iframe>` element
// may help avoid undesirable visual flickering that may be caused by manipulating the `<iframe>` element after creation.
const iframeConfig = {
styles: {
width: "100%",
height: "100%",
border: "none",
display: "block"
}
};
const config = {
appName: "my-app",
container,
context: { ticker: "MSFT" },
iframeConfig
};
// Start the app.
const { id, iframe } = await io.iframes.openApp(config);
// Store the container so it can be removed when a close request is received.
iframeContainers[id] = container;
return { windowId: id, iframe };
};
const { windowId, iframe } = await start();
// Close the app.
await io.windows.findById(windowId).close();API Reference
For a complete list of the available IFrames API methods and properties, see the IFrames API Reference Documentation.