Build and Serve Web Pages with the Web Console

Last updated 6 August 2026

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 .css file as the page's style theme

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. /WP1. Individual pages are accessible as /WP1/Page2. Leave empty to disable serving.

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

var

One bound variable changed

stepperState

A bound stepper's transport or active step changed

sequenceState

A bound sequence's transport or position changed

reload

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

GET /api/pages/{path}/state

Current variable values as JSON — the same payload as the state message

POST /api/pages/{path}/event

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

--bs-accent

Primary brand accent (buttons, progress, highlights)

#089cff (Brainsalt Blue)

--bs-accent-2

Secondary accent

#0859b0

--bs-danger

Stop / cancel actions

#ff5300

--bs-warning

Paused / warning status

#ffba00

--bs-neutral

Pause / neutral state

#5c5c5c

--bs-block-bg

Control block background

#1c1c1c

--bs-text

Default body text colour

#dddddd

--bs-font

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 on 8080.

  • 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 contentVersion in the state message if you write your own client — it tells you the page itself was re-published, as opposed to a value changing.