Skip to main content


The M-Files user interface typically shows two tabs on the right of the screen: Metadata and Preview. As users interact with the object listings (e.g. they select an object), these two tabs react and show the associated metadata and preview respectively.

The User Interface Extensibilty Framework allows third-party developers to add their own tabs alongside the built-in ones, and give you - the developer - control over how and when they are shown.

Creating a New Tab

In most cases the Tab is created to the shellFrame.RightPane using the AddTab method.

// Create a new custom command using IShellFrame instance
const myTab = await shellFrame.RightPane.AddTab(
"my-tab-id", // ID of the tab
"My Tab Name", // Display name of the tab
"_last" // Position of the tab

Showing a dashboard in a tab

Opening a new tab requires a dashboard ID, which is defined in you application manifest file. This will create a new instance of IDashboard which lives inside an <iframe /> until the tab is removed.


Opening too many tabs can affect your application performance.

myTab.ShowDashboard("my-dashboard", {});

Passing data into the dashboard

Custom information can also be passed into the dashboard by providing it as the second argument:

const customData = {
msg: "Sample Message to the Dashboard"
myTab.ShowDashboard("my-dashboard", customData);

The dashboard which was opened using ShowDashboard can retrieve the data from CustomData property.

// Dashboard bootstrap function
function OnNewDashboard( newDashboard ) {

const data = newDashboard.CustomData; // has the data which is passed in ShowDashboard second param
console.log(data.msg); // Logs "Sample Message to the Dashboard"


The Custom Data can include only data which can be serialized using the Structured Cloning Algorithm. This means that you can not pass callback functions inside that data to send responses from the new dashboard back to the opener. However, you can send custom command ID values and custom commands can be given a data parameter.

Passing data the dashboard opener

You can create a custom command which is used to send data back to the opener.

From the opener:

// Create the command, but do not add it to any menu.
const customCommandId = await shellFrame.Commands.CreateCustomCommand(name);

// Listen for the custom commands.
( commandId, data ) => {

// Disregard other commands.
if(commandId !== customCommandId)

// Log out what we were given.
console.log(; // Logs "ExampleObject"

// Show the dashboard and pass the command ID as part of the custom data.
myTab.ShowDashboard("my-dashboard", {
callbackId: customCommandId

From the dashboard we can then return data back to the caller by executing the appropriate command using ExecuteCommand

// Dashboard bootstrap function
async function OnNewDashboard( newDashboard ) {

// Get the command ID
const commandId = newDashboard.CustomData.callbackId;

// Send data back to the caller, in this case object { name: "ExampleObject" }
await shellFrame.Commands.ExecuteCommand(commandId, {
name: "Example Object"


Selecting a Tab

Selecting a tab will display the assosiated Dashboard for the tab.


Unselecting a Tab

Unselecting the tab will hide the assosiated dasboard and make the Tab selection status unselected.


Removing a Tab

Tab can be permanently removed using Remove method. For performance reasons it is recommended to remove tabs which are not actively needed.