Extending Low Code Video
Low Code Video is a hosted application — you do not control its source code. But EnableX provides a webhook function framework that lets you inject your own JavaScript and CSS into the embed at runtime. You write custom code, host it on your server, and register the file URLs with your Low Code application. EnableX loads your files into the embed's browser context and executes your code at the right moments during a video session.
This approach lets you:
- Add entirely new UI components or overlays.
- Override visual styling with custom CSS.
- Run logic when specific room events occur, such as a participant joining or a stream being subscribed.
- Integrate third-party libraries (analytics, Face AI, transcription, etc.) directly inside the session.
EnableX supports two types of external code inserts. Both are loaded via the HTML
<head> of the embed page, making them available for execution before the
video session starts.
JavaScript File
A JavaScript file hosted on your server or a CDN. EnableX injects a
<script src="..."> tag pointing to your file URL into the embed's HTML head.
The file is executed in the embed's browser context, giving it full access to the DOM, global
variables, and the EnableX room object.
<!-- How EnableX loads your JS file in the embed's HTML head -->
<html lang="en">
<head>
<script src="https://YOUR-SERVER/your-custom-script.js"></script>
</head>
<body></body>
</html>
- The URL must be accessible over HTTPS.
- The host server must have CORS enabled.
- The URL can point to a web server path or a CDN endpoint.
CSS File
A CSS file hosted on your server or a CDN. EnableX injects a
<link rel="stylesheet" href="..."> tag into the embed's HTML head.
Use this to override the default visual styles of the embed — colours, fonts, layout, icons,
and any element you can target with CSS selectors.
<!-- How EnableX loads your CSS file in the embed's HTML head -->
<html lang="en">
<head>
<link rel="stylesheet" href="https://YOUR-SERVER/your-custom-styles.css">
</head>
<body></body>
</html>
- The URL must be accessible over HTTPS.
External files are registered through the EnableX Portal under your Low Code application. Open the Extend Embed tab in your Low Code application settings, select the script type (JavaScript or CSS), and enter the HTTPS URL of each file. You can add up to 5 URLs per script type.
Your JavaScript code runs inside the embed's browser context. You have access to:
- All standard browser APIs (DOM, fetch, localStorage, etc.).
- The global room object — the EnableX Web SDK room instance, giving you access to all Web SDK methods and event notifications.
- All global variables and objects defined by the embed's own JavaScript.
Webhook Functions
A webhook function is a named JavaScript function that EnableX calls automatically when a specific room event occurs. Define these functions in your external JavaScript file. If a webhook function is not defined, EnableX simply skips it — only the functions you define are executed.
Room Connection
| Function | When It Is Called |
|---|---|
enxHookRoomConnected() |
The local endpoint has connected to the video room and is ready to communicate. |
enxHookRoomDisconnected() |
The local endpoint has disconnected — due to network loss, an explicit disconnect action, or session end. Use enxEvents.roomDisconnected to read the reason. |
enxHookRoomReconnected() |
The local endpoint has successfully re-connected after a previous disconnection. |
User Connection
| Function | When It Is Called |
|---|---|
enxHookUserConnected() |
Another user has joined the video room. |
enxHookUserDisconnected() |
Another user has left the video room. |
Moderated Entry
| Function | When It Is Called |
|---|---|
enxHookRoomAwaited() |
The local user is waiting in the lobby for the moderator's permission to join. |
enxHookRoomEntryAllowed() |
The moderator has permitted the waiting user to enter the room. |
enxHookRoomEntryDenied() |
The moderator has denied entry to the waiting user. |
Streams
| Function | When It Is Called |
|---|---|
enxHookStreamSubscribed() |
The local endpoint has successfully subscribed to a remote participant's stream. |
Messaging & Signalling
| Function | When It Is Called |
|---|---|
enxHookCustomSignalReceived() |
The local endpoint has received a custom signal broadcast by another participant in the room. |
Event Data
Each webhook function has access to an enxEvents object that holds the data
delivered with the most recent event. Read these values inside your webhook function to act on
the event details.
| Property | Available In | Description |
|---|---|---|
enxEvents.roomReconnected |
enxHookRoomReconnected() |
Data received when the room reconnects. |
enxEvents.roomDisconnected |
enxHookRoomDisconnected() |
Data received on disconnect. Includes the reason for disconnection. |
enxEvents.userConnected |
enxHookUserConnected() |
Metadata of the connecting user: { clientId, name, role } |
enxEvents.userDisconnected |
enxHookUserDisconnected() |
Metadata of the disconnecting user: { clientId, name, role } |
enxEvents.roomEntryAllowed |
enxHookRoomEntryAllowed() |
Data received when a waiting user is permitted to enter. |
enxEvents.roomEntryDenied |
enxHookRoomEntryDenied() |
Data received when a waiting user is denied entry. |
enxEvents.streamSubscribed |
enxHookStreamSubscribed() |
Data received when a remote stream is subscribed. |
enxEvents.customSignalReceived |
enxHookCustomSignalReceived() |
The custom signal payload sent by another participant. |
Example 1 — Room Connection Hooks
The simplest use case: run a block of code when the user connects to the room, and another block when they disconnect. Host the file on HTTPS and register the URL as a JavaScript insert in the Extend Embed configuration.
// custom-hooks.js — hosted on your server at https://YOUR-SERVER/custom-hooks.js
function enxHookRoomConnected() {
// Log to your analytics backend when a session starts
fetch("https://YOUR-SERVER/api/session-started", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ event: "room-connected" })
});
}
function enxHookRoomDisconnected() {
const reason = enxEvents.roomDisconnected
? enxEvents.roomDisconnected.reason
: "unknown";
fetch("https://YOUR-SERVER/api/session-ended", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ event: "room-disconnected", reason: reason })
});
}
Example 2 — Face AI Integration
EnableX Face AI is one of the best use cases for the extension framework. The Face AI SDK is
injected as a JavaScript URL insert. A second file contains your initialisation code placed
inside enxHookRoomConnected(), so it runs only once the room object is available.
Steps:
- Download the EnableX Face AI library and host it on your HTTPS server.
- Write your Face AI initialisation code (example below) in a separate JavaScript file and host it on HTTPS.
- Register both file URLs as JavaScript inserts in the Extend Embed configuration — the Face AI library first, then your initialisation file.
// faceai-init.js — your initialisation code
function enxHookRoomConnected() {
const FaceAI = new EnxFaceAI(); // construct using the loaded library
const config = {
faceDetector: {
maxInputFrameSize: 200,
fullFrameDetection: true
}
};
// localStream is available as a global variable in the embed context
FaceAI.init(null, localStream, config, function(event) {
if (event.result === 0) {
console.log("Face AI initialised successfully.");
}
});
// Listen for face detection events
window.addEventListener("face-detector", function(evt) {
const totalFaces = evt.detail.totalFaces;
// Display count on your custom overlay or send to parent window
document.getElementById("face-count-overlay").textContent =
"Faces detected: " + totalFaces;
});
}
EnxFaceAI constructor is available when your code runs.
Do's
- Read the embed's existing JavaScript to understand which variables and objects are already in use before writing your code.
- Consult the Web SDK documentation to understand how specific SDK methods work when you want to extend functionality.
- Use a unique prefix for any CSS class names or JavaScript object names you introduce — for example,
myApp_overlayPanel— to avoid clashing with existing embed definitions. - Resolve any CORS issues on your server before deploying. The browser will silently refuse to load files that fail CORS checks.
- Test your inserts thoroughly in a development room before deploying to production.
Don'ts
- Do not re-declare variables or objects that already exist in the embed's scope.
- Do not overwrite the values of existing variables and objects. You may read them to inform your own logic, but modifying them can cause unpredictable session failures.
- Do not use HTTP URLs for your hosted files. All inserts must be served over HTTPS.