Skip to main content

Widgets

With ftrack comes a set of standard widgets that can be used on dashboards. In addition to these widgets it is possible for you to build and add your own widgets. A widget is a html page shown in an iframe. This works by creating a web page that uses the ftrack API and show it using the Web view dashboard widget, Custom widget on Overview or when launching an action.

The Custom widget and Web view widgets must be enabled from System Settings > Advanced > Custom widget and can be configured to allow for two way communication between the ftrack UI and the iframe using the postMessage API. For actions, two way communication is always enabled. To create a dashboard with a custom widget you will need the "Manage custom widget" permission.

Communication with the ftrack web UI can be done using a set of predefined topics. The entity details such as id and and type use the same naming as in the ftrack API.

note

Objects such as Task, Shot, Folder, etc. are currently referred to by their inherited type name TypedContext.

note

When serving the widget, you will need to use the same protocol, typically https://, as ftrack is hosted on or the widget will be blocked due to mixed content restrictions in browsers.

tip

If you create a dashboard with a single Web view widget it will automatically stretch to the available vertical space.

Resources and examples

We have created a few example widgets that you can use as an inspiration for your implementation. A minimal example is also included at the bottom of this page.

Libraries

ftrack JavaScript API The JavaScript API client allows developers to write JavaScript scripts, running in a web browser, that talk directly with an ftrack server.

ftrack web widget This small library encapsulates some logic which can be used to build custom dashboard widgets for ftrack. The library exposes an UMD module, accessible as ftrackWidget on the global (window) object.

Basic examples

Creating a custom widget with React This is a basic example utilizing the JavaScript client of the ftrack API and the iframe widget interface to create a custom widget in ftrack, which shows a list of projects.

React Example Widget - This example shows how the JavaScript API can be used in conjunction with ES2015React and Webpack to build a widget showing notes. ​

User theme

In the ftrack web interface, we support both a light and a dark theme which the users can choose from. To give the user a seamless experience, your custom widget may also support these interfaces.

When the widget is loaded a query parameter with the key theme and the value of either light or dark will be injected into the URL. You can use this value to serve the user one of two stylesheets. A JavaScript snippet of how you can achieve this is seen below.

/\*\* Return query parameter by \*key\*. \*/
function getQueryParameter(key) {
var query = window.location.search.substring(1);
var parameters = query.split('&');
for (var i=0; i<parameters.length; i++) {
var parameter = parameters\[i\].split('=');
if (parameter\[0\] === key) {
return parameter\[1\];
}
}
return null;
}
/\*\* Load stylesheet \*href\*. \*/
function loadStyleSheet(href){
var head = document.getElementsByTagName('head')\[0\];
var link = document.createElement('link');
link.rel = 'stylesheet';
link.type = 'text/css';
link.href = href;
head.appendChild(link);
}
// Get theme as set in ftrack from query parameter and inject a stylesheet.
var theme = getQueryParameter('theme') || 'light';
loadStyleSheet('theme-' + theme + '.css');

Supported topics

The following topics are supported:

ftrack.widget.ready

Should be sent from the widget when the widget has loaded and is ready to receive topics from the application. Once the application receive this topic it will respond by sending the ftrack.widget.load topic. The ready topic

{
topic: "ftrack.widget.ready";
}

ftrack.widget.load

Sent when the iframe loads and contains information about the current entity and credentials for the current user that can be used with the ftrack API. It has the following structure:

{
topic: 'ftrack.widget.load',
data: {
entity: {
id: 'eb16970c-5fc6-11e2-bb9a-f23c91df25eb',
type: 'TypedContext'
},
credentials: {
serverUrl: 'https://some-server.ftrackapp.com',
apiUser: 'username',
apiKey: '577ffa44-e702-47f3-b831-4c1115ebf48e'
},
theme: 'dark'
}
}

The data will always contain credentials, but may contain entity for a single entity such as when used on a dashboard and selection when used as an action user interface widget.

ftrack.widget.update

Sent when the ftrack UI navigates to an entity. This event will only be triggered if the widget is used under a project and user navigates in the left outliner tree view. It has the following structure:

{
topic: 'ftrack.widget.update',
data: {
entity: {
id: 'eb16970c-5fc6-11e2-bb9a-f23c91df25eb',
type: 'TypedContext'
}
}
}

ftrack.application.open-sidebar

Can be sent from the widget to open the sidebar for an entity in the ftrack UI and should look like:

{
topic: 'ftrack.application.open-sidebar',
data: {
id: 'eb16970c-5fc6-11e2-bb9a-f23c91df25eb',
type: 'TypedContext'
}
}

ftrack.application.open-actions

Can be sent from the widget to open a window display available for the specified selection. The message should be formatted like the following:

{
topic: 'ftrack.application.open-actions',
data: {
selection: \[{
id: 'eb16970c-5fc6-11e2-bb9a-f23c91df25eb',
type: 'TypedContext'
}\]
}
}

ftrack.application.navigate

Can be sent from the widget to navigate to another entity in the ftrack UI and should look like:

{
topic: 'ftrack.application.navigate',
data: {
id: 'eb16970c-5fc6-11e2-bb9a-f23c91df25eb',
type: 'TypedContext',
module: 'project'
}
}

The module can be omitted to keep the currently active module active. Otherwise it should specified as one of the following:

  • overview
  • project
  • planning
  • report
  • my_tasks
  • system_settings
  • account_settings

Example

This is a simple example of a web page that could be used as a Web view widget.

<html>
<head>
<title>Example</title>
<script type="text/javascript">
// Open sidebar for a hardcoded entity.
window.openSidebar = function () {
window.parent.postMessage(
{
topic: "ftrack.application.open-sidebar",
data: {
id: "ae67656a-b3ce-11e1-8ed3-f23c91df25eb",
type: "TypedContext",
},
},
window.credentials.serverUrl,
);
};
// Navigate to a hardcoded entity.
window.navigate = function () {
window.parent.postMessage(
{
topic: "ftrack.application.navigate",
data: {
id: "ae67656a-b3ce-11e1-8ed3-f23c91df25eb",
type: "TypedContext",
},
},
window.credentials.serverUrl,
);
};
// Listen to messages.
window.addEventListener(
"message",
function (event) {
var content = event.data;
console.debug("Got " + content.topic + " event.", content);
if (content.topic === "ftrack.widget.load") {
//Store credentials for later.
window.credentials = content.data.credentials;
} else if (content.topic === "ftrack.widget.update") {
// Load new data.
}
},
false,
);
// Inform application that we are ready to receive messages.
window.addEventListener("DOMContentLoaded", function () {
window.parent.postMessage(
{
topic: "ftrack.widget.ready",
},
"\*",
);
});
</script>
</head>
<body>
<a href="#" onclick="openSidebar();">Open sidebar</a>
<a href="#" onclick="navigate();">Navigate</a>
</body>
</html>

Security

Since the current users API credentials are passed to the widget, the URLs that can be used to show custom widgets can be restricted from Advanced settings.

Iframe permissions

When creating widgets, the iframes have specific permissions set to allow enhanced functionality. These permissions are part of the iframe's feature policy, which allows the page to use certain features that might otherwise be restricted. For widgets in ftrack, the iframes have the following permissions:

  • fullscreen: Permits the iframe to request to go into fullscreen mode.
  • clipboard-write: Allows the iframe to write to the system clipboard.
  • clipboard-read: Enables the iframe to read from the system clipboard.

These permissions are useful for creating more interactive and user-friendly widgets. For instance, clipboard access is used to create a widget that needs to copy or paste content to and from the clipboard. The fullscreen permission is particularly useful for widgets that benefit from a larger viewing area, such as detailed reports and graphs.

Requesting fullscreen from a widget

To request fullscreen from a widget, you can use the Fullscreen API. However, remember that this action must be triggered by a user gesture, such as clicking a button or link. Below is a code example that demonstrates how to implement a button that, when clicked, requests the iframe to enter fullscreen mode.

<!DOCTYPE html>
<html>
<head>
<title>Fullscreen Example</title>
</head>
<body>
<button id="fullscreenOpen">Enable Fullscreen</button>
<button id="fullscreenClose">Disable Fullscreen</button>
<script>
const openButton = document.querySelector('#fullscreenOpen');
const closeButton = document.querySelector('#fullscreenClose');
openButton.addEventListener('click', openFullscreen);
closeButton.addEventListener('click', closeFullscreen);
function openFullscreen() {
document.documentElement.requestFullscreen();
}
function closeFullscreen() {
document.exitFullscreen();
}
// Add browser prefixes if targeting older browsers
</script>
</body>
</html>

This code snippet includes a simple button that, when clicked, triggers requestFullscreen on the document. It's important to include vendor prefixes to ensure compatibility across different browsers.