The capture cascade
Screenshots are taken in two stages, and it is worth understanding which one you get, because their fidelity differs.
Stage one — the browser's own screen capture. Pixel-exact: it is a picture of what the screen actually showed, including everything CSS can do. The browser asks the user for permission once per capture, and that prompt is expected behavior, not a failure — it appears only after the user clicks "Capture screenshot", never on page load.
Stage two — the DOM renderer. No permission prompt, works everywhere including iOS Safari, and reconstructs the page from the DOM rather than photographing it. That reconstruction is very good and has named limits, listed under what the DOM stage does not reproduce.
screenshot.strategy picks the behavior:
| Value | Behavior |
|---|---|
auto (default) | try stage one, fall back to stage two when it is unavailable or declined |
native | stage one only |
dom | stage two only — no permission prompt ever |
off | no screenshot button at all |
Which stage produced a given screenshot is recorded on the report, so a maintainer can tell an exact picture from a reconstruction.
Whatever the stage, the reporter sees the screenshot before sending and can discard or retake it. Nothing is uploaded until they attach it.
What ends up in the frame
The visible viewport, not the whole page. screenshot.viewport_only is on by default and
both stages honor it, so a report about something further down the page arrives as the band
the reporter was actually looking at. That is usually the point — but it is worth knowing
before you go looking for the rest of the page in the image.
Stage one captures whatever the reporter agreed to share. The browser owns that choice, and this package does not get to make it: Chromium narrows the picker to the current tab, elsewhere the reporter can pick another window or the whole screen, and what they pick is what arrives. Two consequences worth carrying: a report can contain more of their desktop than either of you intended, and region redaction covers regions of your page — it has no reach into a window that is not yours.
The byte cap is enforced on the server only
screenshot.max_bytes (8 MB) is checked after the upload lands, and the browser is never
told the number. Lowering it is the one change here that can strand a reporter: the
capture is produced, uploaded, refused, and nothing on the client knows to try again smaller,
so they get a capture-and-reject loop with no way out of it. If your captures really are too
large, lower screenshot.scale — that is the knob the browser obeys — and leave the cap
where the renderer's own output was sized against it.