# Heatmap

The heatmap shows where people touch each screen of your app, and the friction detectors flag the spots where those touches did nothing. There are no events to add: the SDK sees every touch.

## Turn it on

In Studio’s device panel, open the **Overlays** menu and pick **Heatmap**. Every touch is drawn on the simulator as a blob, coloured by how many other touches are near it: a lone tap is green, a crowded spot is red. New touches never change the colour of the ones already there.

## What it shows

- **Every touch.** Not only taps on controls, but taps on pictures, text and empty space, which is where people try things you didn’t build.
- **One screen at a time.** The heatmap shows the touches made on the screen your app is on, and follows it when the screen changes. The **Overlays** menu’s screen filter picks another screen, or **All screens**.
- **Touches that stay with the content.** On a list, a blob moves with the row that was touched as you scroll, and leaves the view when the row does.
- **Swipes as arrows.** From where the finger went down to where it lifted, thicker for a faster swipe, with a dashed line to where the list stopped scrolling.

## See an earlier session’s touches

Every session keeps its touches, so you can draw an earlier one over the device:

- **A past run.** In **Analytics**, pick the run and press **Show heatmap on device**.
- **A recording, as you scrub it.** In the **Replay** player, turn on **Heatmap**. The heatmap shows the touches up to the playhead and follows it as you scrub or play. **All so far** switches to the **last 5 seconds** before the playhead. Turn on **Drive device** too, and the app goes to each screen as the recording reaches it.

A label at the top of the screen names the session on view. Press it, or pick any overlay, to go back to the live session. Your agent reads the same touches with the `product_heatmap` tool.

If your project builds for iOS and macOS, the Analytics screen’s **iOS**, **macOS** and **All** switch picks whose runs you see, as on [Product analytics](https://squiggle.sh/docs/product).

## What a drag meant

A drag on a `react-native-gesture-handler` pan is also read as one of four intents: a swipe to dismiss, a pull to refresh, a drag to reorder, or a scrub. Each is a guess with its evidence attached: how the finger moved, and what the app did next.

- **high**: the motion fits and the app did the matching thing. A dismiss popped a screen, a refresh sent a request, a reorder or a scrub changed what was on screen.
- **possible**: the motion of a dismiss or a reorder fits in every respect, but the app did nothing that confirms it. A pull or a scrub moves like an ordinary drag, so those two are only ever labelled when the app refreshed or the value followed the finger.

A drag that fits no intent is left unlabelled. A pull on a list that is not scrolled to its top is never read as a refresh. In Studio, the Analytics screen lists a run’s intents under **Gestures**; click one to see the motion and the outcome it rests on. Your agent reads the intents per screen with `product_heatmap` and `include: ["intents"]`.

## Which element a touch landed on

While your app is connected, the Analytics screen’s **Touched elements** list counts the touches on each control, per screen: the heatmap, one element at a time. A touch is named by the control it pressed. When it pressed nothing your app renders, such as a native tab bar, Studio names what the accessibility tree of a simulator it launched had under the finger, if it read that tree within the second before the touch, and the row says so. A touch neither can name is counted as not attributed, never given a nearby element’s name. A past run keeps no element names, so the list is for the live run only.

## What your app needs

Nothing. `<Squiggle>` records every touch by default. To stop it, set `touchCapture={false}`; see the [SDK reference](https://squiggle.sh/docs/reference/sdk).

## More

- [Friction and the journey](https://squiggle.sh/docs/analytics/friction): Rage taps, dead zones and confusion, and the screens a session went through.
- [Product analytics](https://squiggle.sh/docs/product): Friction across every session, with screens, funnels and retention.
