demo · v138

Visibility State Timeline

Chrome 138 adds visibility_state and is_top_level to crash reports. This page records your tab's visibility transitions in real time — switch to another tab and come back — then shows exactly what those two new fields would look like inside a crash report body sent to your Reporting API endpoint.

Current visibility
visible
document.visibilityState: visible
document.hidden: false
Transitions recorded: 0
Page loaded visible is_top_level: true

Crash report body — before vs after Chrome 138

Before Chrome 138
type: "crash"
url: "https://example.com/app"
age: 0
body: {
  crashId: "abc123"
  reason: "oom"
}

Was this the visible tab? Unknown.
Was this an iframe crash? Unknown.
Priority? Guess.
Chrome 138+
type: "crash"
url: "https://example.com/app"
age: 0
body: {
  crashId: "abc123"
  reason: "oom"
  is_top_level: true,
  visibility_state: "visible"
}

Visible tab crash → page on call.
Iframe crash → lower priority.

Triage priority matrix

visibility: visible
visibility: hidden
is_top_level: true
P0 — user-visible crash, page on call immediately
P2 — background tab OOM, monitor trend
is_top_level: false
P1 — embedded frame crash (e.g. ad, widget) in visible tab
P3 — background iframe, low priority noise
Simulate a crash report
Click "Generate report" to preview the crash report body.
// Receiving crash reports at your endpoint
// POST /reporting-endpoint  Content-Type: application/reports+json
[{
  "type": "crash",
  "url": "https://example.com/page",
  "body": {
    "crashId": "...",
    "reason": "oom",
    "is_top_level": true,     // NEW in Chrome 138
    "visibility_state": "visible"  // NEW in Chrome 138
  }
}]

// Route crashes by priority
function priority(report) {
  const { is_top_level, visibility_state } = report.body;
  if (is_top_level && visibility_state === 'visible') return 'P0';
  if (is_top_level) return 'P2';
  if (visibility_state === 'visible') return 'P1';
  return 'P3';
}

see also