The Desktop Client includes an embedded browser that loads web pages as integrations. These integrations can serve as custom panels or dashboards that run directly alongside your cameras and layouts.
Unlike the REST API or Cloud API, which interact with a server over HTTP, the JavaScript (JS) API runs inside the client's embedded browser and interacts directly with the Desktop Client. Use the JS API to build internal control panels, dashboards, or automation buttons rather than remote management scripts.
Prerequisites
Before starting this tutorial, ensure you have the following:
Python 3.12 or higher (used to run a local HTTP server)
Familiarity with HTML, CSS, and JavaScript
The Desktop Client installed on your machine
How API initialization works
The JS API is available only when a page runs inside the Desktop Client as a registered integration with API access enabled. The client exposes the API through a global window.vms object and two initialization flags:
window.isVmsApiEnabled: A boolean flag that indicates whether the JS API is available. If you open the page in a standard browser, this flag returnsfalseand thewindow.vmsobject does not exist.window.vmsApiInit: A callback function that the Desktop Client calls after setting up the API. Do not call or accesswindow.vmsbeforewindow.vmsApiInitexecutes.
Every JS API integration uses the following basic workflow:
Check
window.isVmsApiEnabled.Define
window.vmsApiInitto run your application code once the API is ready.
Create the web application
Follow these steps to create a webpage that initializes the JS API and displays the current tab name.
Step 1: Set up the project directory
Create a project folder on your machine.
Inside the folder, create a file named
index.html.Create a subfolder named
cssand add astyle.cssfile to hold your custom styles.
Step 2: Add the page HTML
Add the base HTML structure to your index.html file. This code includes a fallback banner that appears when the page opens outside the client or before the API loads, as well as a main app section that remains hidden by default (display: none).
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>In-Client JavaScript API — Hello World</title>
<link rel="stylesheet" href="./css/style.css">
</head>
<body>
<!-- Fallback banner shown when API is unavailable -->
<div id="banner" class="viewfinder">
<div class="status" id="statusPillBanner">
<span class="dot"></span>JS API Object Initialization Required
</div>
<h1>Add this page as an Integration</h1>
<ol class="steps">
<li>Open Main Menu → Add</li>
<li>Choose Integrations...</li>
</ol>
<img class="frame-img" src="./img/integration_inclient_js_api.png" alt="Steps to add this page as an integration in Desktop Client">
</div>
<!-- Main application content -->
<div id="app" class="viewfinder" style="display:none">
<div class="status is-live" id="statusPillApp">
<span class="dot"></span>JS API Object Initialized completely!
</div>
<h1>Congratulations!</h1>
<p id="hello"></p>
</div>
</body>
</html>Step 3: Add the API initialization logic
Add a <script> tag before the closing </body> tag in index.html. This script handles UI toggling, checks if the API is enabled, and retrieves data from window.vms.
<script>
// Toggles visibility between the fallback banner and the main app
function showApp(isConnected) {
document.getElementById("banner").style.display = isConnected ? "none" : "block";
document.getElementById("app").style.display = isConnected ? "block" : "none";
}
// Fallback for standard browsers or non-integration loads
if (!window.isVmsApiEnabled) {
window.onload = () => showApp(false);
}
// Entry point for Desktop Client integration execution
window.vmsApiInit = async () => {
showApp(true);
const helloEl = document.getElementById("hello");
helloEl.innerHTML = `This Integration is now running inside tab <span>${window.vms.tabs.current.name}</span>.`;
};
</script>Serve the page locally
The Desktop Client requires a valid URL (HTTP or HTTPS) to load integrations. It does not load raw file:// paths.
Open your terminal or command prompt.
Navigate to the directory containing your
index.htmlfile.-
Start a local Python HTTP server on port 1234:
python3 -m http.server 1234 Confirm that your server is running by opening
http://127.0.0.1:1234in a browser. The fallback banner should appear.
Register the Integration in the client
Open the Nx Witness Desktop Client.
Navigate to Main Menu → Add → Integrations...
Enter your local server URL (e.g.
http://127.0.0.1:1234) and enable API access.Open the newly added integration tab, then drag it onto your viewing area.
The fallback banner disappears, and the page displays a greeting containing the current tab name.
Next steps
Now that you initialized the JS API, you can use the window.vms object to interact with client features:
Add resources to layouts: Use
window.vms.tab.addItem(resourceId, {})to display camera streams.Listen for tab events: Connect to
window.vms.tabs.currentTabItemAdded.connect(...)to respond when scene items change.Authenticate API calls: Access
window.vms.authto retrieve server and cloud tokens.Customize UI elements: Use
window.vms.self.setMinimalInterfaceMode(true)to hide unnecessary window controls.
To view complete implementation examples, visit the Nx Open GitHub Repository - js_api_examples.
Comments
0 comments
Article is closed for comments.