Skip to main content
Pro Plan5 minutesBeginner

Frustration Tracking

Surface rage clicks, dead clicks, and error clicks to spot UX pain points without watching every replay.

frustrationrage-clickdead-clickerror-clickux
Last updated:

Frustration Tracking surfaces three high-signal interactions that almost always indicate UX pain: rage clicks, dead clicks, and error clicks. Use it as a triage shortcut into the pages and elements that confuse or break for real visitors.

What gets tracked

Three click patterns are captured automatically once the feature flag is on.

TypeDefinition
Rage click3+ clicks within 600ms on the same element or 30×30px area. The user is hitting something that looks clickable but is not responding.
Dead clickA click on a non-interactive element with no DOM mutation within 1 second. Looks clickable, isn't.
Error clickA click that triggered a JavaScript error within 100ms. The click broke something.

These three click types are the full set the tracker captures today. There is no extra configuration: when the feature flag is on, the tracker watches for all three.

Privacy guarantees

Frustration events store only diagnostic signals about the element that was clicked — never the contents of the page around it.

What is captured:

  • The element's CSS selector and a short DOM breadcrumb (e.g. main > section > button.checkout-confirm)
  • The element's visible label or text, capped at 100 characters (e.g. the word "Submit" on a button)
  • The element's ARIA role and aria-label, where present
  • The element's computed cursor style (used to flag a "looks clickable but isn't" mismatch)
  • Click coordinates relative to the viewport
  • The page URL and title
  • The frustration type and timestamp
  • The session and visitor IDs the rest of your analytics already use

What is not captured: form values, file content, the contents of other elements on the page, or any other PII. All strings are bounded defensively. If a visitor has Global Privacy Control enabled, frustration tracking is skipped along with the rest of behavioural processing.

Enable it for a website

  1. Open Settings → Advanced for the website you want to track.
  2. Scroll to Feature Flags and turn on Frustration Tracking.
  3. Reload any open page on the site so the tracker picks up the new feature flag (it refreshes within ~5 minutes automatically).

The toggle is gated to the Pro plan and above.

Where to view it

Open the Errors tab in your dashboard, then switch to the Frustration sub-tab.

You'll see three panels:

  • Spotlight — a hero card at the top that auto-selects the highest-priority issue based on event count, unique users affected, recency, and whether it started after your last deploy. The card opens with a plain-language What happened sentence ("A visitor clicked the element labelled 'Submit' on /checkout but nothing happened"), a likely-cause diagnosis, a one-click Copy selector button, a ready-to-paste Reproduce in DevTools snippet, and a Copy for ticket button that bundles everything for handing to a developer.
  • Frustration trend — three sparkline cards (Rage / Dead / Error), one per type, showing event counts over the selected range. Toggle to a combined line chart with the Cards / Lines switch in the top-right.
  • Top hotspots — a sortable worklist where each row is a single broken element on a single page. Each row shows the selector, page path, visible element label, and counts per type. Click any row to expand: read the same plain-language summary, copy the selector, view recent events, and (for error clicks) see the matching JS error inline. Background-container clicks (clicks that bubbled up to <main>, <body>, or <html> from empty whitespace) are flagged with a muted Background badge so you can skip them at a glance.

You can filter by frustration type (Rage / Dead / Error), URL prefix, and time range (1h / 24h / 7d / 30d).

Reading the dashboard

The "Top hotspots" table is your worklist. Each row is a single broken element on a single page — sortable by priority.

Both the Spotlight card and each expanded row share the same triage layout:

  • A plain-language What happened sentence — readable to anyone on your team, no technical knowledge required.
  • A Likely cause diagnosis tuned to the click type and the element's visible signals. The dashboard reads the element's cursor style and tag name to call out the smoking-gun cases ("CSS says clickable, the tag is not a button — make it a real <button> or <a>", or "stuck loading state — handler may throw silently") rather than dumping a generic definition on you.
  • A Reproduce in DevTools snippet — paste it into the page's console and every matching element gets a red outline + a [zenovay] match log line, so you can find the broken element instantly.
  • A Copy selector button (for jumping into DevTools' element inspector) and a Copy for ticket button (for handing the whole context — page, element, type, counts, suggested fix — to a developer in one paste).
  • For error clicks: the linked JavaScript error message and a Copy fingerprint button so you can pivot into the Errors tab.
  • The last few events on the same element with viewport coordinates and session ids.

The Spotlight card auto-selects the highest-priority issue using:

priority = (rage × 3 + dead × 1.5 + error × 5) × ln(unique_users + 1) × recency_boost

Recency boost is 1.5× within the last 24 h. Background-container clicks are heavily de-prioritised so they never end up as the Spotlight. If a hotspot started after your last GitHub deploy, the row gets an amber NEW badge — that's almost always a regression.

Tips for triage

  • Start at the Spotlight. Read the plain-language sentence, scan the likely-cause diagnosis, copy the DevTools snippet, paste it into the page's console — the broken element will be outlined.
  • Hand it to a developer in one paste. If you're a PM or founder spotting an issue, the Copy for ticket button bundles the page, element, click type, counts, and a suggested fix into a single message you can drop into Linear, Jira, or Slack.
  • Watch for the NEW badge. Hotspots flagged as new since your last deploy are almost always regressions worth fixing first.
  • Pair rage with error. Rage clicks on the same selector as an error click point to a real exception — fix the JS error and the rage usually disappears.
  • Dead clicks reveal expectations. A page where many visitors dead-click the same div tells you what they expected to be clickable. Either make it interactive, or remove the visual cue (e.g. cursor: pointer).
  • Skip the Background rows. Rows tagged Background are clicks that landed on empty whitespace and bubbled up to a container; they very rarely indicate a real bug.

Limitations

  • Frustration events are retained for roughly 90 days, then purged automatically. They are a triage signal, not a long-term archive — investigate hotspots while they're fresh.
  • Event capture is throttled at the tracker layer to avoid runaway counts on broken pages — you'll see a representative sample, not every click.
  • Hotspots aggregate across the lifetime of stored data; the chart respects the selected time range.

Was this article helpful?