# Heatmap capture

> How ClickClacks captures what a page looks like for heatmaps: when a capture is taken, what is masked in the browser before upload, how to hide more with data-cc-mask and skip selectors, and how to turn capture off.

- Canonical URL: https://clickclacks.io/docs/heatmap-capture
- Section: Tracking
- Last updated: 2026-09-26

To draw a heatmap, ClickClacks needs a picture of the page. The tracker takes one now and then, in the visitor’s browser, and masks anything sensitive before it leaves.

Heatmaps are part of the Pro plan. Capture is set per website source, under **Heatmaps › Capture & masking** in the app, and it’s on for new sources. Clicks themselves come from [autocapture](https://clickclacks.io/docs/autocapture.md#click); this page is about the picture they’re drawn on.

## How a capture is taken {#how}

1. After a pageview, the tracker asks ClickClacks whether this page still needs a capture today. The answer is cached for the tab’s session.
2. At most one browser per page, per device size, per day is asked to capture. Device sizes are mobile (under 600 px wide), tablet (under 1,024 px) and desktop. Everyone else skips straight away, so almost no visitor ever renders anything.
3. The chosen browser loads a small helper, `heatmap-screenshot.js`, renders a screenshot, and uploads it. [Masking](https://clickclacks.io/docs/heatmap-capture.md#always-masked) is applied to a copy of the page before rendering, not to what your visitor sees.
4. If the page is too large to capture, or the visitor resizes the window or opts out mid-way, nothing is sent, and a later visit tries again.

## Always masked {#always-masked}

These are masked in every capture, and can’t be turned off:

- Numbers and email addresses in page text, replaced with dots.
- Every `input`, `textarea` and `select`, including anything typed into them.
- Video, canvas, embedded pages (`iframe`, `object`, `embed`) and anything `contenteditable`.
- Anything marked `data-cc-mask` or `data-private`, with everything inside it.
- `value`, `placeholder`, `title` and `alt` attributes, and inline event handlers.

A masked element becomes a plain grey block of the same size, so click positions still line up. If the whole page (its `<html>` or `<body>`) is marked private, nothing is captured.

> **Ordinary text and images stay visible**
>
> Masking is balanced so heatmaps stay recognisable. Names, addresses, avatars and account details that aren’t in a form field are shown unless you mask them.

## Masking more {#mask-more}

Two ways, and you can use both:

- **In your markup:** add `data-cc-mask` (or `data-private`) to an element. `data-cc-mask` also stops click text being recorded inside it.
- **In the app:** under **Also skip these**, add CSS selectors such as `.customer-avatar` or `#invoice-table`, up to 64 of them. They apply to future captures from that source, with no deploy.

```html
<!-- Hidden in captures, with its space kept; no click text recorded inside -->
<section data-cc-mask>
  <h2>Your invoices</h2>
  …
</section>

<!-- data-private works the same way for captures -->
<img class="customer-avatar" data-private src="/avatars/ana.png" alt="">
```

## What is sent and kept {#what-is-sent}

Each capture holds the masked screenshot plus a layout of the page’s visible elements: their position and size, tag name, up to two classes and an id, and the rectangles where lines of text sit. The layout never contains text, form values, URLs or markup. Captures are kept for 30 days, and the newest one for each page and device size is always kept.

## Turning capture off {#turn-off}

- **For a source:** switch off **Capture page screenshots** under Heatmaps › Capture & masking.
- **For one site or page:** add `data-capture="off"` to the script tag. Events are still sent.
- **For one visitor:** an [opted-out](https://clickclacks.io/docs/consent.md) visitor is never asked to capture.

```html
<script async src="https://app.clickclacks.io/c.js" data-key="pk_live_3f9a1c7e5b2d4f6a8c0e1b3d" data-domains="acme.com,www.acme.com,app.acme.com" data-capture="off"></script>
```

## Next steps {#next}

- [Heatmaps](https://clickclacks.io/features/heatmaps): what you can do with them.
- [What’s collected](https://clickclacks.io/docs/privacy.md): the rest of what the tracker sends.
