Assesses what a page's heatmap is telling you and recommends concrete changes. Pulls click / rageclick / scroll-depth data for a URL, names the hot elements by cross-referencing autocapture events on the same page, and can create a saved heatmap the user opens in PostHog, then summarizes the behavior and proposes improvements.
Add this skill
npx mdskills install PostHog/assessing-heatmaps@PostHog? Sign in with GitHub to claim this listing.Expert heatmap analysis workflow with strong coordinate-to-meaning fusion and actionable UX insights
1---2name: assessing-heatmaps3description: "Assesses what a page's heatmap is telling you and recommends concrete changes. Pulls click / rageclick / scroll-depth data for a URL, names the hot elements by cross-referencing autocapture events on the same page, and can create a saved heatmap the user opens in PostHog, then summarizes the behavior and proposes improvements.\nTRIGGER when: user asks what a heatmap shows, why people aren't clicking something, where users rage-click, how far they scroll, what to change on a page based on heatmap/click data, or to 'analyze/assess/review the heatmap' for a URL.\nDO NOT TRIGGER when: the user only wants to create a saved heatmap screenshot with no analysis (use heatmaps-saved-create directly), or is asking about session replay in general (use investigating-replay)."4---56# Assessing heatmaps78A heatmap answers "where do people interact with this page?" — clicks, rage clicks, mouse movement, and how9far down they scroll. The data is pure geometry: `pointer_relative_x` (0..1 across the viewport), `pointer_y`10(absolute pixels down the page), and a count per spot. **It does not know what was clicked.** Turning11"lots of clicks at (0.5, 220)" into "lots of clicks on the Pricing nav link" is the whole job, and it comes12from cross-referencing autocapture on the same URL.1314## Core principle: coordinates + meaning1516You can't see the page — there is no screenshot in your context. A good assessment fuses two sources and17leans on autocapture to supply the layout/identity you can't see:18191. **Heatmap data** — where interactions land and how far people scroll (`heatmaps-list`).202. **Autocapture** — what element sits under the hot spots, by element text / selector on the same page. This21 is what turns coordinates into meaning; without it you only have dots.2223When the user wants to _see_ the heatmap, create a saved heatmap (Step 4) — that renders the page with the24data overlaid for them to open in PostHog. You reason from the data; they look at the picture.2526## The flow2728### Step 1: Pin the page and window2930You need an exact `url_exact` (one page) or a `url_pattern` (regex, to aggregate across query strings). Confirm31the URL with the user if ambiguous. Default to the last 7 days; widen to 30 if volume is low. Heatmap data is32retained for 90 days.3334### Step 2: Pull the data3536Call `heatmaps-list` once per signal you care about (or query the `heatmaps` table directly via SQL — see the37querying-posthog-data skill, `models-heatmaps`):3839- `type: "click"` — the primary "what draws attention" map.40- `type: "rageclick"` — repeated frustrated clicks. **The single strongest "something is broken or41 misleading" signal.** Any meaningful rageclick cluster deserves a callout.42- `type: "scrolldepth"` — how far people get. Use it to find the fold and spot CTAs that sit below where most43 people ever scroll.4445Use `aggregation: "unique_visitors"` when you care about how many people (not how many clicks); `total_count`46exaggerates a few heavy clickers.4748### Step 2b: Above the fold — read the `fold` summary4950For the click types, `heatmaps-list` returns a `fold` object alongside `results`:5152- `pct_below_fold` — share of non-fixed interactions that landed **below the user's initial viewport** (they53 had to scroll to reach them). This is one of the highest-value findings: content people actively click that54 sits below the fold is a prime candidate to move up.55- `below_fold_count` / `total_count` — the raw counts behind the percentage (fixed-position elements are56 excluded, since they're always on screen).57- `median_viewport_height` — the typical fold line in CSS pixels, to recommend against.5859Report it concretely, e.g. "the fold is ~600px for most visitors, yet 35% of clicks land below it, so users60scroll before interacting — that content is a candidate for the first screen." **Segment by device** with61`viewport_width_min`/`viewport_width_max` (desktop and mobile have very different folds) and read `fold` per62band rather than blending them.6364Need a distribution rather than a single percentage (e.g. clicks bucketed by how far below the fold)? Drop to65SQL on the raw `heatmaps` table, which has `y` and `viewport_height` in the same scaled units — see the66querying-posthog-data skill, `models-heatmaps`.6768### Step 3: Name the hot elements (autocapture overlap)6970For each notable cluster, find what's actually there. Query autocapture on the same URL — either via the71`exploring-autocapture-events` skill or directly:7273```sql74SELECT properties.$el_text AS text, count() AS clicks75FROM events76WHERE event = '$autocapture'77 AND properties.$current_url = 'https://example.com/pricing'78 AND timestamp >= now() - INTERVAL 7 DAY79GROUP BY text80ORDER BY clicks DESC81LIMIT 2582```8384`elements_chain` gives the selector/DOM path when you need to disambiguate two elements with the same text.85Match autocapture's top elements to the heatmap's hot coordinates: clicks concentrated on something that is86**not** a link or button (plain text, an image, a disabled control) is a classic "users expect this to be87clickable" finding.8889### Step 4: Give the user a heatmap to look at (optional)9091You can't see the page, but the user can. When a visual would help them follow your findings, create a saved92heatmap so they can open the rendered page with the data overlaid in PostHog:93941. `heatmaps-saved-create` with the page `url` (type defaults to `screenshot`). This enqueues a headless95 render — it is asynchronous. Pass `widths` matching the viewport band you analyzed in Step 2.962. Poll `heatmaps-saved-get` (by the returned `short_id`) until `status` is `completed`, then tell the user97 it's ready to view in PostHog.9899This is for the human's benefit — your own reasoning still comes from the Step 2 data and the Step 3100autocapture identity, not from the picture.101102### Step 5: Drill into hotspots (when you need the "why")103104For a surprising cluster, `heatmaps-events` returns the individual sessions behind specific `points`. Hand the105session IDs to the `investigating-replay` skill to watch what people actually did.106107### Step 6: Summarize and recommend108109Produce a short, concrete report:110111- **What the heatmap shows** — top engaged elements, dead zones, scroll reach, and the above/below-the-fold112 click split (e.g. "viewport is ~600px for most visitors, yet 35% of clicks land below it").113- **Problems**, ranked by signal strength — rage-click clusters first, then clicks on non-interactive114 elements, then important CTAs sitting below the scroll cliff, then ignored primary actions.115- **Recommendations** tied to evidence — move/raise a CTA above the fold, make a clicked-but-dead element a116 real link, cut competing elements near a rage-click cluster, etc. Every recommendation should cite the117 signal it came from.118119## Reading the signals120121| Signal | Likely meaning | Typical recommendation |122| ---------------------------------- | --------------------------------------------------------------------------------- | -------------------------------------------------------------- |123| Rage clicks on an element | Broken, slow, or looks-clickable-but-isn't | Fix the handler, add feedback, or make it actually interactive |124| Many clicks on non-link text/image | Users expect it to be clickable | Make it a link/button, or remove the affordance |125| Primary CTA gets few clicks | Buried, low-contrast, or out-competed | Raise it, increase contrast, reduce nearby noise |126| Scroll cliff before key content | Content/CTA is below where people stop | Move it up or add a reason to scroll |127| High % of clicks below the fold | Engaged content sits below the initial viewport — users scroll before interacting | Move the most-clicked elements onto the first screen |128| Hot clicks on nav, cold body | Page isn't delivering; people bail to nav | Re-evaluate the page's core content |129130## Gotchas131132- **Heatmaps must be opted in** (`Team.heatmaps_opt_in`). If `heatmaps-list` returns nothing for a page that133 clearly gets traffic, capture may be off or the URL is wrong — check both before concluding "no134 engagement".135- **Coordinates are scaled** by a factor of 16 in storage; the API already returns CSS-pixel `pointer_y` and136 relative x, so use the API/tool values directly rather than the raw table columns.137- **You can't see the screenshot.** The saved-heatmap render is for the user to open in PostHog; don't claim138 to have looked at the page. Ground every layout claim in autocapture identity + coordinates, not vision.139- **Saved-heatmap rendering is async.** After `heatmaps-saved-create`, poll `heatmaps-saved-get` until140 `status` is `completed` before telling the user it's viewable. Only `screenshot`-type heatmaps render an141 image; `iframe` and `recording` types do not.142- **Mind the viewport.** A desktop click map and a mobile one are different pages' worth of behavior — filter143 with `viewport_width_min`/`viewport_width_max` rather than blending them.144
Full transparency — inspect the skill content before installing.