JavaScript SDK for connecting screen clients to a Drawbridge server.
Drawbridge manages interactive experiences made up of named screens (display panels). Each screen connects to the Drawbridge server over a persistent WebSocket. The server sends commands to change what a screen is displaying; screens report state back (puzzle results, scores, answers) by setting variables.
The SDK handles connection lifecycle automatically: it reconnects after transient network interruptions and buffers outgoing messages while the link is down.
npm install @drawbridgesolutions/js-sdk
import { DrawbridgeConnection } from "@drawbridgesolutions/js-sdk";
const connection = new DrawbridgeConnection({
screen_name: "lobby-display",
});
connection.onScreenChange((screen) => {
console.log("Active screen:", screen);
});
new DrawbridgeConnection({ screen_name })Opens a WebSocket to the Drawbridge server for the named screen. The connection is established immediately and will auto-reconnect if dropped.
screen_name — unique identifier for this screen, must exactly match the name configured in the Drawbridge project and playbook settings.connection.onScreenChange(callback)Registers a function to call whenever the server sends a screen-change command. Only one callback is active at a time — calling this again replaces the previous one.
The callback receives the new screen identifier as a string (e.g. "0", "1", "intro"), as defined in the Drawbridge project configuration. It also fires on reconnect if the server re-sends the current state.
connection.onScreenChange((screen) => {
switch (screen) {
case "idle":
showIdleVideo();
break;
case "intro":
showIntroVideo();
break;
case "puzzle":
showPuzzleScreen();
break;
default:
showIdleVideo();
}
});
connection.getCurrentScreenThe identifier of the most recently received screen, or null if no screen-change command has arrived yet. Updated synchronously on each incoming event — safe to read at any time.
if (connection.getCurrentScreen === "puzzle-active") {
enableInputControls();
}
connection.isConnectedtrue when the WebSocket readyState is OPEN. false during the initial connect, a reconnect pause, or after close() is called. Messages sent while disconnected are buffered and delivered once the link is restored.
setInterval(() => {
statusDot.className = connection.isConnected ? "dot-green" : "dot-red";
}, 1000);
connection.setVariable(variableName, value)Sends a variable update to the server. Variables are the primary way a screen reports state — signalling a completed puzzle, submitting an answer, reporting a score. The server can use these values to trigger transitions, unlock other screens, or drive game logic.
variableName — must match the variable name in the Drawbridge playbook settings exactly (case-sensitive).value — string, number, or boolean.// Signal puzzle completion
connection.setVariable("VAULT_PUZZLE", "DONE");
// Reset after a failed attempt
connection.setVariable("VAULT_PUZZLE", "-");
// Send a numeric score
connection.setVariable("PLAYER_SCORE", 4200);
// Validate a code entry
function checkCode(entered: string) {
connection.setVariable(
"KEYPAD_CODE",
entered === "7734" ? "CORRECT" : "WRONG",
);
}
connection.addEventListener(type, listener, options?)Subscribes to events on the connection's internal EventTarget. Follows the standard EventTarget.addEventListener interface. Useful for fanning out events to multiple listeners without replacing the primary onScreenChange callback.
connection.addEventListener(
"screenReady",
() => {
initializeAnimations();
},
{ once: true },
);
connection.removeEventListener(type, listener, options?)Removes a listener previously registered via addEventListener. The type, listener, and options arguments must match those used when the listener was added.
function onConnected() {
console.log("Connected");
}
connection.addEventListener("connected", onConnected);
// Later:
connection.removeEventListener("connected", onConnected);
connection.close()Permanently closes the WebSocket and disables auto-reconnect. No further messages will be sent or received. Call this when the screen unmounts or the page is about to unload.
window.addEventListener("beforeunload", () => connection.close());
// React
useEffect(() => {
return () => connection.close();
}, []);