Skip to content

Screenshots

Claudezilla screenshots use dynamic readiness detection to capture pages at the right moment, with quality presets to balance file size against detail.

Use the purpose parameter to select a preset, or override with explicit quality and scale values.

PresetQualityScaleUse Case
quick-glance300.25Layout checks, navigation confirmation
read-text600.50Reading content (default)
inspect-ui800.75UI details, small text
full-detail951.00Pixel-perfect inspection
// Quick layout check — small and fast
firefox_screenshot({ purpose: "quick-glance" })
// Default — good for most tasks
firefox_screenshot({ purpose: "read-text" })
// Need to read 12px font sizes
firefox_screenshot({ purpose: "inspect-ui" })
// Override preset with custom values
firefox_screenshot({ quality: 85, scale: 0.6 })

The purpose is a suggestion — explicit quality or scale values always take priority.

Set annotate: true to overlay numbered badges on interactive elements before capture. The response includes a labels map linking badge numbers to selectors.

const result = firefox_screenshot({ annotate: true })
// Response includes:
// {
// dataUrl: "data:image/jpeg;base64,...",
// labels: {
// "1": { selector: "#login-btn", text: "Log In", role: "button" },
// "2": { selector: "a.nav-home", text: "Home", role: "link" },
// "3": { selector: "#email", text: "", role: "input" }
// }
// }

This is useful for vision-model workflows: take an annotated screenshot, identify elements by badge number, then use the corresponding selector to interact.

// 1. Capture with annotations
const shot = firefox_screenshot({ annotate: true, purpose: "inspect-ui" })
// 2. Identify badge #3 is the email input
// 3. Type into it using the selector from labels
firefox_type({ selector: "#email", text: "user@example.com" })

By default, screenshots wait for the page to settle before capturing. The detection pipeline:

  1. Network idle — waits for pending XHR/fetch/script requests to complete
  2. Visual idle — optionally waits for images and fonts (up to 3s)
  3. Render settlement — double requestAnimationFrame + requestIdleCallback

The response includes timing data showing what happened:

{
readiness: {
waitMs: 347,
timedOut: false,
timeline: [
{ t: 0, event: "start" },
{ t: 45, event: "critical_idle" },
{ t: 312, event: "visual_idle" },
{ t: 347, event: "render_settled" }
]
}
}

If the page is already idle, the fast path captures in under 50ms.

ParameterDefaultDescription
maxWait10000Maximum ms to wait before capturing anyway
waitForImagestrueWait for images/fonts to load
skipReadinessfalseSkip all detection (instant capture)
// Text-heavy page — skip image waiting
firefox_screenshot({ waitForImages: false })
// Page is already loaded — instant capture
firefox_screenshot({ skipReadiness: true })
// Give a slow SPA more time
firefox_screenshot({ maxWait: 20000 })

If maxWait is reached, the screenshot is still taken — readiness.timedOut will be true. This prevents hanging on pages with perpetual network activity (analytics pings, websockets).

All screenshot requests are serialized through a mutex to prevent tab-switching collisions when multiple agents capture simultaneously. If another agent holds the mutex for more than 3 seconds, you receive a MUTEX_BUSY error:

MUTEX_BUSY: Screenshot mutex held by another agent.
Holder: agent_ec2e...
Held for: 6234ms
Hint: Use getPageState (no mutex) or retry after delay.

Use firefox_get_page_state as a mutex-free alternative when you only need structured data, not a visual capture.