Browser Render
Monitor JS-rendered pages with deterministic waits and rendered DOM diffs when simple fetch is not enough.
Browser Render
Browser Render is for pages where simple_fetch misses meaningful changes because the DOM is built client-side.
Plan availability: Pro and above.
When to use it
- SPA routes where content appears after JavaScript execution.
- Pages with framework hydration where source HTML is incomplete.
- Targets where simple fetch produces unstable or partial evidence.
How it works
- Load the page in an isolated browser context.
- Wait using deterministic conditions.
- Serialize the rendered DOM.
- Apply ignore rules and compute diffs.
This keeps results reproducible across runs while preserving signal quality.
Eligibility
Browser render is used only when all of these are true:
- Your runtime capability execution mode is browser-enabled.
targetTypeisurl.- Monitor fetch mode is
content.
If any rule is not met, Diffmon falls back to simple_fetch and logs why.
Quickstart
- Create or update a URL monitor.
- Add
browserOptionsfor wait strategy and viewport. - Start with
wait_until: "networkidle"for SPAs. - Add
wait_for_selectorwhen the page has a clear "ready" element. - Keep
ignoreSelectorsfocused on volatile UI regions.
App UI (no API required)
You can configure Browser Render directly in the app:
- Open New monitor (
/app/monitors/new) or an existing monitor settings page. - Set monitor type to URL.
- In Request settings, keep fetch mode at Content.
- Enable Use Browser Render (JavaScript/SPA).
- Set viewport and wait strategy (
wait_until, optional selector, optional delay). - Save settings (existing monitor) or create the monitor (new monitor).
If your plan does not include Browser Render, the toggle is shown as locked with an upgrade hint.
Sandbox preview
Sandbox preview supports Browser Render under the same capability gate:
- Pro+ plans can run sandbox in browser mode.
- Free/Hobby plans receive
FEATURE_LOCKEDfor browser preview requests. - Browser sandbox applies SSRF/resource policy checks and browser wait settings.
- Sandbox runs are metered and rate-limited independently from monitor runs.
API v1 fields
On create/update requests, use browserOptions:
viewport:{ width, height }wait.wait_until:load | domcontentloaded | networkidlewait.wait_for_selector: CSS selectorwait.wait_delay_ms: fixed settle delay (max5000)navigationTimeoutMstotalRunTimeoutMs
On monitor responses, the stored value is returned as browserOptionsJson.
- Unknown keys are rejected on public API v1 requests.
- Browser options are only valid for
targetType="url"with content checks. - Options are stored, but execution still depends on runtime entitlements and eligibility.
viewportrequires bothwidthandheightwhen provided.
API examples
Create a monitor with browser render options:
{
"name": "Pricing Page",
"targetType": "url",
"targetUrl": "https://example.com/pricing",
"checkIntervalMinutes": 5,
"selectSelectors": "#app",
"ignoreSelectors": ".timestamp\n.tracking-id",
"browserOptions": {
"viewport": { "width": 1280, "height": 720 },
"wait": {
"wait_until": "networkidle",
"wait_for_selector": "#app .pricing-table",
"wait_delay_ms": 250
},
"navigationTimeoutMs": 20000,
"totalRunTimeoutMs": 30000
}
}Patch just the wait strategy:
{
"browserOptions": {
"wait": {
"wait_until": "domcontentloaded",
"wait_delay_ms": 100
}
}
}Troubleshooting
BROWSER_WAIT_CONDITION_FAILED: selector did not appear before timeout.BROWSER_NAVIGATION_TIMEOUT: page did not complete navigation in time.BROWSER_POLICY_BLOCKED: request was blocked by SSRF/protocol policy.BROWSER_CONTENT_TOO_LARGE: serialized HTML exceeded capture limit.
Best practices
- Start with
simple_fetchfor static pages. - Upgrade to Browser Render only for routes that need it.
- Keep ignore rules focused on known volatile regions.
- Pair Browser Render with webhook routing for incident automation.