What’s collected

What the tracker keeps in the browser, what it sends, and what it removes before anything is sent. Everything here describes the script’s actual behaviour.

Updated

What’s stored in the browser

The tracker doesn’t set cookies. It keeps a few random IDs in the browser’s own storage, which is separate for every hostname:

KeyWhereHolds
ccplocalStorageA random anonymous ID for this browser.
ccilocalStorageThe ID you passed to identify, if you called it.
ccglocalStorageThe group IDs you set with group, such as a company, if you called it. Empty otherwise.
_cc_caplocalStorageMarkers for heatmap captures already taken, so the same page isn’t captured again.
ccssessionStorageA random session ID.
cclsessionStorageWhen the session was last active. A session ends after 30 minutes without activity.
ccolocalStorageSet to 1 when the visitor opted out, so the choice lasts across page loads.
ccc…sessionStorageThe source’s heatmap capture settings, cached for the tab’s session.

What’s sent

  • Autocaptured events. Pageviews with the page path and, on the first one, the referrer; clicks with the element’s tag, id, first two classes, a short selector, the click position and viewport width; scroll depth. The full list is in Autocapture.
  • Your own events and identify calls, with the properties you pass.
  • With every event, the anonymous ID, the session ID, and the identified ID if you set one.
  • On links between your listed domains, a _ccid parameter with the anonymous ID and session ID, so the next domain can recognise the visitor. Turn it off with data-carry-identity="off". See Domains and identity.

On arrival, ClickClacks adds the visitor’s country and the browser, operating system and device type read from the user agent. (A touch screen is the only device detail the tracker sends, so iPads count as tablets.) The IP address isn’t stored: that’s a per-source setting, and it is off unless you turn it on. Requests from well-known crawlers, such as Googlebot, Bingbot and link-preview bots, are dropped by default.

Sensitive URL parameters

Page paths and referrers keep their query string by default, because that’s where UTM tags live. Before anything is sent, the tracker removes every query parameter whose name matches, ignoring case:

  • code
  • password
  • passwd
  • pwd
  • auth
  • authorization
  • session
  • sessionid
  • sid
  • signature
  • sig
  • otp
  • apikey
  • email
  • phone
  • ssn
  • card
  • cvv

It also removes token, key and secret, and any name ending in one of them after an underscore or hyphen, such as access_token, api_key or client-secret. The #fragment is never sent with page paths.

what the tracker sends
https://acme.com/welcome?utm_source=newsletter&email=ana@acme.com&reset_token=9f2c
                                      ↓
/welcome?utm_source=newsletter

The cross-domain _ccid parameter is removed the same way, so a visitor’s ID never ends up in a recorded path or referrer. To drop the query string from page paths and referrers entirely, add data-query="off" to the script tag. Scrubbing only changes what is sent to ClickClacks, never the URLs on your site.

Click text and masking

A click on a link or button records up to 40 characters of its visible text. Other elements record no text. No text is recorded when the click happens inside:

  • input, textarea or password fields
  • anything contenteditable
  • any element marked data-cc-mask, or inside one

Add data-cc-mask to anything whose text you never want recorded, such as account details. It also removes that part of the page from heatmap captures. To record no click text anywhere, add data-click-text="off" to the script tag.

html
<!-- Left out of heatmap captures, and no click text is recorded inside it -->
<section data-cc-mask>
  <h2>Your invoices</h2>
  …
</section>

Heatmap page captures

To draw heatmaps, the tracker occasionally captures what a page looks like and sends it to ClickClacks. Captures are on by default for each source. You can turn them off for a source in the app, or for a site by adding data-capture="off" to the script tag. The capture is redacted in the browser, before it is sent:

  • Form fields (input, textarea, select, contenteditable) and embedded content (iframe, video, canvas, object, embed) are replaced by plain grey blocks.
  • Anything marked data-cc-mask or data-private, plus any selectors you add to the source’s skip list, is replaced the same way.
  • In the remaining text, every digit and anything that looks like an email address is replaced with dots.
  • value, placeholder, title and alt attributes, and inline event handlers, are removed.
  • If the whole page is marked private, nothing is captured.

Other page text and images are still visible in the capture. Mark anything personal with data-cc-mask, or add data-mask="strict" to the script tag: every character of text becomes a dot, and images, SVGs and background images are left out, so the capture shows only the page’s shape. Heatmap capture explains when captures are taken and how long they’re kept.

Opting a visitor out

js
// When a visitor declines or withdraws consent
window.clickclacks('optOut')

// If they later agree, without a page reload
window.clickclacks('optIn')

optOut drops any events not yet sent, deletes everything in the table above except cco, stops all tracking and remembers the choice, so it holds on every later page load until optIn. Neither can recall events already sent. In opt-in mode the tracker reads only cco, and stores nothing, until the visitor agrees. Consent and opt-out covers consent banners, loading the tracker only after consent, Tag Manager, Do Not Track and Global Privacy Control.

On sign-out, use reset instead: it forgets the identified person but keeps tracking.

What isn’t scrubbed

The tracker is careful, but it can’t know what your URLs and events mean. It does not:

  • inspect or redact path segments, such as /users/ana@acme.com;
  • redact values under parameter names that aren’t on the list above;
  • check the properties you send with custom events or identify;
  • hide link or button text outside a masked area.

Keep personal data out of paths and event properties, and use data-cc-mask where labels themselves are personal.

Next steps