Displaying Persistent Content in a Tab - A sample using the User Interface Extensibility Framework

This sample creates a basic User Interface Extensibility Framework application consisting of one ShellUI module which shows a persistent browser window within a tab in the right-pane of M-Files. This can be useful to display a web page which is not context-sensitive (e.g. an intranet), persisting the user’s navigation within the browser window as they navigate within M-Files.

The source code for this sample is available within our GitHub Samples and Libraries repository.

This sample extends the previous samples. Whilst all basic steps will be covered, more detail may be found in other samples.


This sample does not show how to create a local development folder or to deploy the code to the M-Files server. It is assumed that a local development folder already exists, and that is the location in which the development is occurring.

Creating the application structure

Creating the application definition file

Into this folder we will create an application definition file. This file must be named appdef.xml. The application will use version 3 of the client schema (as we are only targeting newer M-Files versions), and the supported platform will be set as desktop only. The application will declare a single Shell UI module (with its code in main.js), and no dashboards.

<?xml version="1.0" encoding="UTF-8"?>
<application xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	<name>Display persistent web page</name>
	<description>Shows how to display a persistent web page (e.g. an intranet) in a tab.</description>
	<publisher>M-Files Corporation</publisher>
	<copyright>(c) M-Files Corporation 2017</copyright>
		<module environment="shellui">

Ensure that your application has a unique GUID by using a GUID generator, such as this one.

Creating the module

Next we will create a module file to contain our actual application logic. We will:

// NOTE! This code is for demonstration purposes only and does not contain any kind of
// 		 error handling. MUST be revised before using in production.

"use strict";

// A handle to the persistent browser that will be used
// across all shell frames.
var persistentContentHandle = null;

function OnNewShellUI( shellUI )
	/// <summary>Executed by the UIX when a ShellUI module is started.</summary>
	/// <param name="shellUI" type="MFiles.ShellUI">The shell UI object which was created.</param>
	// This is the start point of a ShellUI module.
	// Register to be notified when the shell ui is started.
		getShellUIStartedHandler(shellUI) );
	// Register to be notified when a new normal shell frame (Event_NewNormalShellFrame) is created.
	// We use Event_NewNormalShellFrame rather than Event_NewShellFrame as this won't fire for history (etc.) dialogs.
	// ref: https://www.m-files.com/UI_Extensibility_Framework/index.html#Event_NewNormalShellFrame.html
		handleNewShellFrame );

function getShellUIStartedHandler(shellUI)
	/// <summary>Returns a function which handles the OnStarted event for an IShellUI.</summary>

	return function()
		// The shell UI is now started and can be used.

		// Create the persistent browser window (but do not show it).
		persistentContentHandle = shellUI.CreatePersistentBrowserContent(
				defaultvisibility: false
			} );

function handleNewShellFrame(shellFrame)
	/// <summary>Handles the OnNewNormalShellFrame event for an IShellUI.</summary>
	/// <param name="shellFrame" type="MFiles.ShellFrame">The shell frame object which was created.</param>
	// The shell frame was created but it cannot be used yet.
	// The following line would throw an exception ("The object cannot be accessed, because it is not ready."):
	// shellFrame.ShowMessage("A shell frame was created");
	// Register to be notified when the shell frame is started.
	// This time pass a reference to the function to call when the event is fired.
		getShellFrameStartedHandler( shellFrame) );
function getShellFrameStartedHandler(shellFrame)
	/// <summary>Returns a function which handles the OnStarted event for an IShellFrame.</summary>
	return function() {
		// The shell frame is now started and can be used.
		// Create a new tab for the content to be shown in.
		// ref: https://www.m-files.com/UI_Extensibility_Framework/index.html#MFClientScript~IShellPaneContainer~AddTab.html
		// Tab ids ref: https://www.m-files.com/UI_Extensibility_Framework/#SidePaneTabs.html
		var tab = shellFrame.RightPane.AddTab( "myPersistentContent", "Intranet", "_last" );

		// Load the content into the tab.
		tab.ShowPersistentContent( persistentContentHandle );

		// Show the tab.
		tab.visible = true;

Testing the application

Opening the vault shows a new tab next to home, named Intranet. Selecting the tab shows the web page that was specified.

Intranet tab selected

Note that any navigation within the persistent browser window will be kept when navigating within views in M-Files.