Quick answer: Worker mode runs the game on a Web Worker with no DOM. Move document/window access to a DOM-side script, communicate via the script messaging API.

A Construct 3 game uses Execute JavaScript to call document.getElementById. It works in the editor preview but crashes the exported build — Worker mode has no DOM.

Why Worker Mode Has No DOM

Worker mode runs the engine on a separate thread for performance and smoothness. Web Workers can’t touch document or window — those exist only on the main (DOM) thread.

DOM-Side Scripts

Construct 3 supports DOM-side scripts: JS files set to run on the DOM thread, not the worker. Put DOM-touching code there:

// domSide.js (set "Purpose" to DOM-side in script properties)
const el = document.getElementById("overlay");
el.style.display = "block";

Worker ↔ DOM Messaging

From worker-side game code, communicate with DOM-side scripts via the addon SDK’s post-message API, or use Construct’s built-in runtime.postToDOM / AddDOMMessageHandler pattern.

Or Disable Worker Mode

Project Properties → Use Worker = No. The game runs on the DOM thread, DOM access works directly — at the cost of the smoothness Worker mode provides. Acceptable for DOM-heavy games.

Verifying

Export with Worker mode on. DOM-side scripts manipulate the page; worker-side game logic runs smooth. No “document is not defined” crashes.

“Worker mode trades DOM access for smoothness. Move DOM code to DOM-side scripts.”

For games embedding in a custom HTML page (ads, leaderboards), design the DOM↔worker message contract early — retrofitting it is painful.