Skip to main content

Custom Iframes

Custom Iframes introduce a way to build UI that is developed by the plugin itself.

Up until now, to add UI elements, a plugin needed to ask Web App 3 to do it on its behalf. This helps with delegating responsibility and assuring the plugin adheres to the established design principles.

One major downside is that UI becomes very reliant on Web App 3's versions and subsequently release cycle. The current capabilities make building a simple plugin quite easy, and we are not taking this away, however the need to offer support for use cases with more complex UI is there.

Iframe Manager

IframeManager holds all the iframes created by the plugin and allows you to load them on Web App 3. Custom Iframes are identified by an unique id which is used every time the iframe needs to be referenced.

Several options are available in terms of the type of the Iframe.

Here is how to add an iframe to the manager:

window.plugin.iframeManager.add({
id,
url: `https://pexip.com`,
type: 'sidePanel', // can be any of the types mentioned above
});

And here is how to toggle rendering an iframe via a button for example:

const button = await plugin.ui.addButton({
position: 'toolbar',
icon: 'IconChat',
tooltip: 'Chat',
});

button.onClick.add(() => {
void plugin.ui.togglePlugin({id});
});

Because a custom iframe is effectively a separate plugin in terms of logic, we have gone with togglePlugin instead of toggleIframe when it comes to naming the interface.

Slotted Iframe

Custom iframes can loaded into pre-defined slots on Web App 3's side. Currently, we only support the side panel. The side panel is where the chat and participants list live.

Floating Iframe

Custom Iframes can also be loaded anywhere on the app by specifying the following properties:

export interface IframeInitPosition {
width?: string;
height?: string;
x?: string;
y?: string;
}

export type IframeProps = {
id: string;
url: string;
type: 'draggable' | 'fixed';
initPosition?: IframeInitPosition;
headerTitle?: string;
}

The difference between the draggable and fixed types is that when we type the iframe as draggable, we can move it around the same way we can move the selfview.

If the initPosition is left undefined, the iframe is initially position in the following manner:

{
width: '400px',
height: '200px',
x: '16px',
y: '72px'
}

Loading an external resource

The following example will add a button to the toolbar which will toggle between loading and unloading Pexip into the side panel as an iframe.

const id = 'ID';
window.plugin.iframeManager.add(id, `https://pexip.com`);

const button = await plugin.ui.addButton({
position: 'toolbar',
icon: 'IconPexipLogo',
tooltip: 'Pexip',
});

button.onClick.add(() => {
void plugin.ui.togglePluginSidePanel({id});
});

Loading an internal resource

There are several ways to load an internal resource. We think the approach that will provide the best context separation between custom iframes within a single plugin is achieved via vite.config.js.

Let's take the example plugin as a case study (plugin-example.zip) and assume we have an external service that feeds in customer service requests that we want to display in a custom iframe.

The file structure might look something like this:

    |-- src
index.ts
requests.ts
index.html
requests.html
...rest of the files in the plugin-example

index.ts will be your main main entry point that holds the UI to toggle the iframe

requests.ts will hold the iframe code. For this to be ran, it needs to be included in requests.html

<!doctype html>
<script src="./src/requests.ts" type="module"></script>

To match this file structure the vite.config.js will have to be like so:

export default {
base: './',
build: {
target: 'esnext',
rollupOptions: {
input: ['./index.html', './requests.html'],
output: {
entryFileNames: `assets/[name].js`,
},
},
},
};

The example code in index.ts will then look like this:

const id = 'ID';
window.plugin.iframeManager.add(
id,
'https:/${WEBAPP3-ADDRESS}}/webapp3/branding/${PATH-TO-YOUR-PLUGIN}/custom.html',
);

const button = await plugin.ui.addButton({
position: 'toolbar',
icon: 'IconPexipLogo',
tooltip: 'Pexip',
});

button.onClick.add(() => {
void plugin.ui.togglePluginSidePanel({id});
});

Note that PATH-TO-YOUR-PLUGIN will be the same as the one in your branding manifest. If your plugin config in the manifest is "plugins": [{"src": "./plugins/example-plugin/index.html"}], the source of your custom iframe will be https:/${WEBAPP3-ADDRESS}/webapp3/branding/plugins/example-plugin/custom.html