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.