Build and Serve Web Pages with the Web Console
Build operator-facing web pages directly inside Backstage and serve them to any browser on the network. Use the built-in drag-and-drop page editor to lay out controls that connect to your show logic -- sequencers, steppers, volume faders, calibration controls, and live data bindings -- without writing code.
Note: This page covers the Web Console -- a first-class show-control entity with its own window and embedded page editor. It is not the same as the Node Editor Presenter (the drag rectangle inside a node graph). The Node Editor Presenter places ImGui widgets on a canvas for Backstage Hub operators; the Web Console produces HTML pages served over the network to any standard web browser. If you need the Node Editor Presenter, see Build a Presenter Area.
Before you start
- Backstage is running and you have a project open
- The built-in web server is enabled (Settings > Webserver)
- If you want to bind page elements to node data, you have a node graph with labelled datatype nodes (String, Float, Int, Color, or Bang)
- If you want show-control blocks (Sequencer, Stepper, Output, Matrix Mixer, Calibrator Lite, Broadcast Scheduler), the corresponding entities or labelled nodes exist in your project
Steps
1. Open the Web Consoles window
Open the Web Consoles window from View > Web Consoles, or switch to the Web Console workview preset with Ctrl+5.
The window has two panes: a narrow entity list on the left and the page editor on the right.
2. Create a Web Console entity
In the entity list, click + Add Web Console. A new entity appears in the list with a default name (e.g. "Web Console 1"). Double-click the name to rename it.
The page editor loads immediately on the right. On a brand-new entity, the block palette opens automatically so you can start building.
3. Add blocks to the page
Drag blocks from the block palette (right sidebar of the page editor) onto the canvas. Blocks are grouped into categories:
Backstage (show-control blocks that reference entities directly):
-
Sequencer -- play/pause/stop and progress bar bound to a sequence
-
Stepper -- transport controls and step buttons bound to a Backstage stepper entity
-
Output -- audio output volume (master fader + optional per-channel faders + mute)
-
Matrix Mixer -- audio matrix mixer volume and mute
-
Calibrator Lite -- start alignment, black level, cancel, status, progress, and snapshot restore. Works for a scene's external Calibrator too, despite the label
-
Broadcast Scheduler -- read-only week plan with legend, current time, and enable toggle
Node (blocks that follow whatever entity a labelled node currently drives):
-
Sequencer (Node), Stepper (Node), Broadcast Scheduler (Node) -- same controls as above, but bound by node label rather than entity
The Backstage and Node blocks cover the same entities as the show-control protocol's domains — sequencers, steppers, output and matrix mixers, calibrators, broadcast schedulers and labelled node endpoints — and perform the same operations. A Web Console page is the browser-facing route to that control surface; the protocol is the machine-facing one. See Remote Control for the per-element detail.
One gap: NDI input slots are controllable over the protocol but have no block here. Drive them through a labelled node instead.
Ui Elements:
-
Heading, Text Block, Text Input, Text Area, Image, Button, Slider, Color Picker, Divider, Link
Layout:
-
2 Columns, 3 Columns, Container, Section, Grid (configurable rows/columns), Sidebar Layout
Display:
-
Badge, Progress Bar, Table (configurable rows/columns/header), Ticker (scrolling text)
Media:
-
Video, Audio, Embed / iFrame
Each block shows a tooltip on hover describing what it does and how it binds.
4. Configure block properties
Select any element on the canvas. Its properties appear in the right sidebar of the page editor (this is the GrapesJS component panel, not the Backstage Inspector).
-
Show-control blocks (Sequencer, Stepper, etc.) are pre-bound to their entity when dropped. You can change the binding in the properties panel.
-
Ui Elements can be bound to labelled datatype nodes using the Value Node, Text Colour Node, Background Node, and Click Node dropdowns. These bindings make the element update live from the node graph.
-
Tables and Grids have Columns and Rows properties to resize the grid. Table cells are drop targets -- drop other blocks into them.
-
Images use a Source dropdown to pick from page media files. Drag an image file onto the canvas to add it; local
file://images are embedded automatically so the page works on any machine.
5. Manage multiple pages
The page editor has a page tab bar above the canvas.
-
Click + to add a new page
-
Double-click a tab to rename a page
-
Right-click a tab for Set as Default, Duplicate, or Delete
The default page (marked with a * prefix on its tab) is served when a browser visits the base serve path.
6. Apply your changes
Use the toolbar buttons at the top of the page editor:
|
Button |
Action |
|---|---|
|
Apply |
Save the current page content (enabled only when there are unsaved changes) |
|
Revert |
Discard unsaved changes and reload the last saved state |
|
Reset |
Clear all content and reset the page to default (asks for confirmation) |
|
Open in Browser |
Open the served page in the system's default web browser |
|
Open in Window |
Open the served page in Backstage's built-in Web View window |
|
Export Style |
Download the page's CSS theme (or a starter template if none is set) |
|
Import Style |
Upload a |
If you click Open in Browser or Open in Window while there are unsaved changes, Backstage warns you and offers to save first.
7. Configure serving in the Inspector
Select the Web Console entity in the list. Its properties appear in the Inspector on the right side of the main Backstage window under a Web Console header.
|
Setting |
Description |
|---|---|
|
Name |
Display name of the entity |
|
Serve path |
URL path where the page is served, e.g. |
|
Serve on web server |
Enable to host the page on the built-in web server. Browsers can then open the page and receive live updates. |
|
Default page |
Which page is served at the base path (empty = the first page) |
A green status dot next to the entity name in the list indicates the page is being served. A red/stopped dot means it is not.
8. Open the page from a browser
Once Serve on web server is enabled and a Serve path is set, any device on the same network can open:
http://<server-hostname>:8080/<serve-path>
The page updates live -- show-control blocks reflect real-time state, and datatype-node bindings push changes automatically.
Port 8080, not 80. Backstage runs two HTTP servers: 8080 serves the API and these pages, while 80 is a separate web server for Backstage Viewer downloads and node-hosted pages. A connection refused on 80 is usually this mix-up.
Integrating with a served page
A served page keeps itself in step with Backstage over a WebSocket, and the same channel is open to anything else you write — a hand-built page, a kiosk shell, or an external dashboard that wants live show state without polling.
ws://<server-hostname>:8080/ws/<serve-path>
What the server sends
On connect you receive one state message carrying every current variable, typed:
{
"type": "state",
"contentVersion": 3,
"vars": {
"myVar": { "type": "string", "value": "Hello" },
"brightness": { "type": "number", "value": 0.75 },
"tint": { "type": "color", "r": 255, "g": 128, "b": 0, "a": 255 }
}
}
After that, updates arrive as they happen:
|
Message |
Meaning |
|---|---|
|
|
One bound variable changed |
|
|
A bound stepper's transport or active step changed |
|
|
A bound sequence's transport or position changed |
|
|
The page content itself was re-published — fetch it again |
contentVersion increments when the page is re-published, which is how a client tells a content change from a data change.
What the client sends
{ "type": "click", "name": "myButton" }
{ "type": "stepperAction", "action": "next", "step": 0 }
{ "type": "sequenceAction", "action": "Play" }
{ "type": "varChange", "name": "brightness", "value": "0.5", "varType": "number" }
Values travel as strings with varType naming the intended type, mirroring how the node bindings parse them.
Polling instead
Where a WebSocket is impractical, the same state and events are reachable over plain HTTP:
|
Endpoint |
Purpose |
|---|---|
|
|
Current variable values as JSON — the same payload as the |
|
|
Send a click, a stepper or sequence action, or a variable change |
The JavaScript bridge in a Backstage-built page prefers the WebSocket and falls back to polling on its own, so you only need these when writing your own client.
These endpoints sit behind the same HTTP Basic credentials as every other REST endpoint on port 8080 — the Automation API and the Remote UI included. Changing that username and password changes it for all of them.
Options explained
Page editor blocks -- datatype binding
Any UI element that supports bindings shows these dropdowns in its component properties:
|
Setting |
Description |
Values |
|---|---|---|
|
Value Node |
Bind the element's value to a labelled datatype node |
Dropdown of labelled String, Float, Int, Color, and Bang nodes |
|
Text Colour Node |
Bind the element's text colour to a Color node |
Dropdown of labelled Color nodes |
|
Background Node |
Bind the element's background to a Color node |
Dropdown of labelled Color nodes |
|
Click Node |
Bind a click event to a Bang/String node |
Dropdown of labelled Bang and String nodes |
Page body background
Select the page body (click the empty canvas area) to access per-page background properties:
|
Setting |
Description |
Values |
|---|---|---|
|
Background Color |
Page body background colour |
Color picker |
|
Background Image |
Image used as the page body background |
Media file dropdown |
|
Background Size |
How the background image is sized |
(default), Cover, Contain, Stretch, Original |
|
Background Repeat |
Whether the background image tiles |
(default), No repeat, Tile |
Theming (CSS variables)
The page and all control blocks reference a set of CSS variables for consistent styling. Export the theme to see (and edit) these variables:
|
Variable |
Purpose |
Default |
|---|---|---|
|
|
Primary brand accent (buttons, progress, highlights) |
|
|
|
Secondary accent |
|
|
|
Stop / cancel actions |
|
|
|
Paused / warning status |
|
|
|
Pause / neutral state |
|
|
|
Control block background |
|
|
|
Default body text colour |
|
|
|
Default font family |
"Noto Sans", Arial, Helvetica, sans-serif |
Quick-switch colour presets are available per control block: Brainsalt Blue, Deep Blue, Cyan, Orange, Amber, Green.
Common Mistakes
-
Page shows stale content after editing -- You edited the page but did not click Apply. The served page only updates after you save. Backstage warns you if you try to open the page with unsaved changes.
-
"Open in Browser" is greyed out -- The entity has no Serve path set, or Serve on web server is not enabled. Configure both in the Inspector.
-
Show-control blocks are missing from the palette -- The block palette only lists entities and labelled nodes that already exist. Create the sequencer, stepper, mixer, calibrator or broadcast scheduler entity first, then reopen the page editor. The palette refreshes automatically.
-
Datatype binding dropdowns are empty -- Only datatype nodes with a Label set appear in the binding dropdowns. Open the node editor and assign a label to each String, Float, Int, Color, or Bang node you want to bind.
-
Images do not display on another machine -- If you used a local file path, the image is embedded automatically. However, if the image was added via an external URL, that URL must be reachable from the browser viewing the page.
-
Connection refused from a browser -- you are on port
80. Pages are served on8080. -
Looking for an NDI input-slot block -- there is not one. Route slots through a labelled node, or over the protocol.
Tips
-
The Web Console workview preset (
Ctrl+5) arranges the workspace with the Web Consoles window and Inspector side by side for efficient page editing. -
Dropping a show-control block onto the page pre-assigns its binding to the entity or node it represents. You do not need to configure the reference manually after dropping.
-
Tables and Grids have configurable Columns and Rows properties. Their cells are droppable containers -- nest other blocks inside them for complex layouts.
-
Use Export Style to download the CSS theme, edit the CSS variables in a text editor, and Import Style to apply your custom branding across all pages and served output.
-
The WebConsole node in the node graph is a lightweight reference to a Web Console entity -- it does not host the page. Use it to programmatically switch which page is served (via its "Page" input) or to resolve entity IDs (via the GetWebConsole node).
-
Watch
contentVersionin thestatemessage if you write your own client — it tells you the page itself was re-published, as opposed to a value changing.
Related
-
Remote Control -- The routes for driving Backstage from outside, and a page per controllable element.
-
Enable and Configure the Show-Control Protocol -- Enabling and configuring the protocol that backs the same control surface for control systems.
-
Build a Presenter Area -- The Node Editor Presenter (ImGui-based, for Backstage Hub). Different from the Web Console.
-
Remote Control: Node Endpoints -- Node endpoints, which is how Ui Elements on a page bind to the graph.
-
Build and Serve Web Pages with the Web Console -- Includes the Webserver setting that enables page serving.


