In this video, I’ll show how to use a “random” Javascript control inside Business Central. I show the entire process from downloading till it works inside BC.

In this video, Erik demonstrates how to take a JavaScript control found on the internet and integrate it directly into Business Central using AL control add-ins. Rather than picking a typical business-oriented JavaScript control, he goes for something far more impressive: Babylon.js, a full 3D rendering engine that runs in the browser. By the end, he has interactive 3D animated graphics running inside a Business Central page.
Why Babylon.js?
There are plenty of JavaScript controls you could embed in Business Central — WYSIWYG editors, charting libraries, and other common business tools. But Erik wanted to make things more interesting. Babylon.js is an open-source 3D rendering engine named after the famous capital city of Babylonia in Mesopotamia. It lets you render fully interactive 3D graphics directly in the browser, and there’s a huge community with tons of resources around it.
The goal: take a minimal Babylon.js demo (a sphere and a plane), get it working inside Business Central, and then level it up to display an animated retro planet scene — all through a control add-in.
Starting with a Minimal Example
The approach begins with a simple standalone HTML file that renders a basic 3D scene — just a sphere sitting on a plane. Looking at the source code of that page, we can identify the key ingredients:
- Script references — several JavaScript files that make up the Babylon.js engine and related libraries (including Ammo.js for bullet physics)
- CSS styles — to make the canvas fill the available space
- A canvas element — the HTML5 element where 3D rendering happens
- A script block — the actual scene creation code (camera, lights, objects, etc.)
This HTML file essentially becomes the “plan of attack” for building the control add-in.
Creating the Control Add-In
The first step is downloading all the required JavaScript files and saving them into the extension project. These go into a subfolder (in this case, a folder called Babylon) within the extension package.
Next, create the control add-in definition file. One nice thing about control add-ins is that they don’t require an object ID — you just give them a name:
controladdin Babylon
{
Scripts =
'Babylon/ammo.js',
'Babylon/babylon.js',
'Babylon/babylonjs.materials.min.js',
'Babylon/babylonjs.loaders.min.js',
'Babylon/babylonjs.postProcess.min.js',
'Babylon/babylonjs.proceduralTextures.min.js';
StartupScript = 'Babylon/startup.js';
HorizontalStretch = true;
VerticalStretch = true;
event ControlReady();
}
Key points about this definition:
- The
Scriptsproperty lists all the JavaScript library files that need to be loaded, with relative paths from the extension root. - The
StartupScriptpoints to a separate JavaScript file that will run when the control initializes. HorizontalStretchandVerticalStretchare set totrueso the control fills all available space.- The
ControlReadyevent tells Business Central when the control has finished preparing itself.
Building the Startup Script
All control add-ins run inside an iframe, and Microsoft places a div section with the ID controlAddIn inside that iframe. The startup script needs to:
- Get a reference to that container element
- Dynamically insert the HTML canvas element
- Apply styles
- Run the 3D scene creation code
- Signal Business Central that the control is ready
The startup script uses insertAdjacentHTML to dynamically create the canvas element inside the control add-in container — a technique Erik covered in his earlier video on dynamic HTML rendering:
var htmlContainer = document.getElementById('controlAddIn');
htmlContainer.insertAdjacentHTML('beforeend',
'<canvas id="renderCanvas" style="width:100%;height:100%;"></canvas>'
);
// Scene creation code (from the Babylon.js example)
var canvas = document.getElementById("renderCanvas");
var engine = new BABYLON.Engine(canvas, true);
var createScene = function () {
var scene = new BABYLON.Scene(engine);
var camera = new BABYLON.FreeCamera("camera1",
new BABYLON.Vector3(0, 5, -10), scene);
camera.setTarget(BABYLON.Vector3.Zero());
camera.attachControl(canvas, true);
var light = new BABYLON.HemisphericLight("light",
new BABYLON.Vector3(0, 1, 0), scene);
light.intensity = 0.7;
var sphere = BABYLON.MeshBuilder.CreateSphere("sphere",
{ diameter: 1, segments: 32 }, scene);
sphere.position.y = 1;
var ground = BABYLON.MeshBuilder.CreateGround("ground",
{ width: 6, height: 6 }, scene);
return scene;
};
var scene = createScene();
engine.runRenderLoop(function () {
scene.render();
});
window.addEventListener("resize", function () {
engine.resize();
});
// Signal BC that we're ready
Microsoft.Dynamics.NAV.InvokeExtensibilityMethod('ControlReady', []);
Instead of creating a separate CSS file, Erik simply adds an inline style directly on the canvas element — width:100%; height:100%; — which is simpler for this use case.
Adding the Control to a Page
With the control add-in defined and the startup script ready, you need a page to display it. Note that even though the object is called a “control add-in” in AL, when you place it on a page you use the usercontrol keyword:
In the video, Erik demonstrates this on a Customer Card page extension:
pageextension 56100 "Customer Card JS" extends "Customer Card"
{
layout
{
addfirst(content)
{
part(WB; Workbench)
{
ApplicationArea = all;
}
}
}
}
The corresponding app.json ties everything together:
{
"id": "9853f749-37c2-45e7-8838-300209cb5e8b",
"name": "JavaScriptWorkBench",
"publisher": "Hougaard.com",
"version": "1.0.0.0",
"dependencies": [
{
"id": "63ca2fa4-4f03-4f2b-a480-172fef340d3f",
"publisher": "Microsoft",
"name": "System Application",
"version": "16.0.0.0"
},
{
"id": "437dbf0e-84ff-417a-965d-ed2bb9650972",
"publisher": "Microsoft",
"name": "Base Application",
"version": "16.0.0.0"
}
],
"platform": "16.0.0.0",
"idRanges": [
{
"from": 56100,
"to": 56149
}
],
"showMyCode": true,
"runtime": "5.0"
}
First Test: It Works!
After deploying to a Docker-based sandbox and navigating to the page, the result is immediate: a 3D rendered sphere and plane appear directly inside Business Central, and you can interact with the scene using your mouse.
Erik then demonstrates that you have full control over the scene by modifying parameters. For example, changing the sphere’s diameter from the default to a smaller value and redeploying shows the sphere shrinking — confirming that the JavaScript code is fully controllable.
Leveling Up: The Retro Planet
With the basic demo working, Erik goes for the more impressive example — the animated retro planet from the Babylon.js demo gallery. The approach is the same copy-paste methodology:
- View the source of the planet demo page
- Find the
createScenefunction (one large function containing all the planet rendering logic) - Copy it into the startup script, replacing the simple sphere/plane scene
- Redeploy
After a brief moment of suspense — and it works on the first try. A fully animated, interactive 3D planet with orbiting elements appears directly inside Business Central.
What We Actually Typed
If you strip away all the copy-pasting, the amount of original code is remarkably small:
- The control add-in definition — mostly just file references plus about four lines of configuration
- Two lines in the startup script — to prepare the canvas container
- One line at the end — to signal
ControlReady - Everything else was copied from the Babylon.js example
Where Could You Take This?
Erik suggests several practical applications for this technique:
- Add functions to communicate between AL and the 3D JavaScript code
- Add events so that clicking objects in the 3D scene sends data back to Business Central
- Display 3D product renderings on the Item Card — imagine having a live 3D model of your products right on the card
- Use any open-source JavaScript library — charts, editors, maps, or anything else the web has to offer
Summary
Integrating JavaScript controls into Business Central through AL control add-ins is far easier than it looks. The process follows a consistent pattern: download the JavaScript libraries, create a control add-in definition that references them, write a small startup script that sets up the HTML elements and fires the ControlReady event, and add the control to a page. The fact that you can get something as complex as an interactive 3D rendering engine running inside Business Central with minimal original code demonstrates just how powerful and flexible this approach is. Babylon.js is open source with a huge community, but the same technique applies to virtually any JavaScript control you find on the internet.