Debugging a web page
Set a breakpoint in the JavaScript a page loads, and the page stops there while it runs — with the values it had at that moment.
A script that draws on a canvas or reads the document can't be run on its own: on its first line it asks for something that only exists inside a page. So Circuitry runs it where it belongs — in the preview — and stops it there.
This works for three kinds of file:
- a
.jsfile a page loads with<script src="…"> - a
<script>block written inside an HTML file - a
.jsxor.tsxcomponent, in its own preview
Getting a page on screen
Make one with New → Code → HTML, or open an existing .html from the Files browser in the sidebar. Its scripts come from the same folder, so a game.js sitting beside index.html is the ordinary case.
An HTML file opens with two halves: the Code you write and the Preview that runs it. Switch between them — or show both at once on a wide screen — with Preview and Code in the status bar. The preview re-runs as you type; runs it again on demand.
Open the script the same way, from the Files browser. You can keep both as tabs and move between them while debugging.
Turning it on
Set a breakpoint on the line you want to stop at:
- Touch — press and hold the line, then choose Breakpoint from the bar that appears. It reads Clear breakpoint when there's already one there, so the label always says which way the tap will throw it.
- Mouse — click the margin to the left of the line number.
- Keyboard — press F9 with the cursor on the line.
The Breakpoint item only appears in files that can actually stop, so if it isn't in the bar, that file has no debugger behind it.
The first time you mark a line in a script, Circuitry looks for the page that loads it — starting in the same folder, then the rest of the project — and offers to debug it there. You get two ways forward:
- Turn on — start debugging and stay where you are. The page picks it up the next time it renders.
- Turn on & open page — start debugging and go to the page.
If you'd rather not right now, say so; the next breakpoint you add asks again. You can also turn it on at any time from Debug → Debug in Page.
In a script's status bar the button shows the state: dimmed when debugging is off, lit when it's on. Beside it, opens the page and runs it, because running the script by itself is not what you meant.
When it stops
Execution parks on the line, and a bar tells you where:
Red dots are your breakpoints. The highlighted line with the arrow is where it stopped — it scrolls there on its own, even if the file wasn't open when the breakpoint hit.
The bar appears on the page and on the script, so the controls are wherever you are:
- Continue — run on to the next breakpoint
- Step — run the next line
- Stop — stop debugging; the page keeps running
- Show — open the file at the paused line (only shown when you're not already looking at it)
The page carries on running while it's stopped — this one is sitting on its title screen with the script parked at line 143.
The Debugger panel
The sidebar's Debug tab opens when a breakpoint hits. It lists every breakpoint in the file and every variable in scope at the moment it stopped — expand an object to look inside it.
What a pause is — and what it isn't
It stops the code that hit the breakpoint. The rest of the page keeps going. Animation carries on, timers keep firing, and a click still does something. That's worth knowing before you conclude a value is wrong: what you're looking at is one paused piece of a page that is otherwise still alive.
Your files are never changed. The breakpoints are added to the copy the preview runs, never to what's on disk.
Lines that can't pause
Some places can't stop, and Circuitry says which and why rather than leaving a dot that never fires. A notice names the line and the reason:
- Inside a component — a React component can't be paused without changing what it hands back to React. Break in an event handler or a plain function instead.
- Inside a
useMemo,useCallbackoruseEffectcallback — React reads what these return, so the same applies. - Inside a generator, a getter or setter, or a class constructor.
- Top-level code in a plain
<script>— move it into a function, or load the file as a module. - A line where no statement starts — a blank line, a comment, or a closing brace.
One thing that can't be detected and is worth watching for: if you break inside a small function whose result is used immediately — a sort comparator, or the callback in map or filter — that function behaves differently while debugging is on. Turn it off when you're done.
Reading the page's console
The preview has its own log, off until you ask for it. Press LOG in the status bar and confirm; the preview reloads so the log starts at the page's first line.
It records console.log and friends, plus uncaught errors and unhandled rejections — which is usually the line that explains a blank page, and which never reaches console.error on its own. All shows everything, Problems narrows it to errors and warnings. On a phone it opens full screen, which is the only console available there.
Tips
- Stop on the line before the one you suspect. Variables show the values going in, which is usually the question.
- A breakpoint in a loop or an animation frame stops every time round. Step moves a line at a time; Continue goes to the next hit.
- Changing a breakpoint reloads the preview so the change takes effect — expect the page to start over.
- Editing the file also reloads the preview, so breakpoints stay in step with what you've written.
Related
- Debugging Workflows — breakpoints in workflow code and code documents
- Full IDE: Code Editor
- Web Design
- Build in the browser