Tracker API

Everything the browser tracker understands: the attributes on its script tag and the six commands it takes. There’s no other surface.

Updated

Script attributes

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-consent="opt-out" data-respect-gpc="on"></script>
AttributeMeaning
srcRequiredhttps://app.clickclacks.io/c.js, or https://<your custom domain>/c.js. Events go to the same origin the script loads from.
asyncRecommendedLoads without blocking the page.
data-keyRequiredThe source’s browser key, pk_live_…. Without it the tracker does nothing.
data-domainsRequiredComma-separated hostnames the tracker may run on, matched exactly and case-insensitively. Links between them carry identity.
data-consentOptionalopt-out (the default, also when absent) starts tracking on load. opt-in waits for optIn.
data-respect-gpcOptionalon keeps tracking off, and makes optIn do nothing, while the browser sends Global Privacy Control.
data-queryOptionaloff sends page paths and campaign data without the query string.
data-click-textOptionaloff records no text for clicked links and buttons.
data-carry-identityOptionaloff neither adds _ccid to links between your domains nor reads it on arrival.
data-captureOptionaloff stops heatmap captures from this page. Events are unaffected.
data-maskOptionalstrict masks all text and leaves out images in heatmap captures.
nonceOptionalYour CSP nonce. Passed on to the heatmap helper the tracker loads.

The tracker reads these from its own tag when it starts, and only starts when the page’s hostname is in data-domains, data-key is set, and browser storage works. Otherwise window.clickclacks is never defined.

Commands

signature
window.clickclacks(command: string, ...args): void
  • Every command returns undefined and never throws. A call with the wrong arguments, or an unknown command, is ignored.
  • While the visitor is opted out, every command except optIn and optOut is ignored.
  • reset, optOut and optIn are also methods: clickclacks.reset().

event

js
clickclacks('event', 'Report exported', { format: 'csv', rows: 1200 })
  • name: a string of 1–128 characters, not starting with $.
  • properties (optional): a plain object. Functions and undefined values are dropped. Over 2 KB of JSON, the event is sent without them, keeping only path.
  • The page is added as path: the pathname only, never the query string or #fragment. Reports read it as Page. Pass your own path and yours is kept.
  • After identify, the ID is added as $distinct_id. After group, the groups are added as $groups.

Events sent from your servers (the API and the SDKs) carry no page. Add path to their properties if you want one.

Guide: Custom events.

identify

js
clickclacks('identify', 'user_4821', { plan: 'pro' })
  • id: a string of 1–128 characters, your own user ID.
  • traits (optional): a plain object, same rules as event properties. Over 2 KB, only the ID is sent.
  • Sends a $identify event with distinct_id and the traits, and saves the ID for later events in this browser.
  • Links this browser to anyone who identified with the same ID elsewhere. $identify events are free.

Guide: Identify people.

group

js
clickclacks('group', 'company', 'cmp_311', { name: 'Acme', plan: 'pro' })

clickclacks('group', 'company', null)   // leave the group
  • type: 1–64 lower-case letters, digits or underscores, such as company.
  • id: a string of 1–255 characters (numbers become strings), or null to leave the group.
  • traits (optional): a plain object describing the group. Sends a $group_identify event, which is free. Traits that look personal, such as an email or phone number, are dropped unless the source allows them.
  • The browser remembers one ID per type, at most 5 types, and adds them to every later event as $groups, such as { "company": "cmp_311" }.

Guide: Companies and groups.

reset

js
clickclacks('reset')            // or clickclacks.reset()

Forgets the identified ID and groups, drops events not sent yet, and starts a new anonymous ID and session. Tracking continues. Call it on sign-out.

optOut

js
clickclacks('optOut')           // or clickclacks.optOut()

Drops events not sent yet, cancels retries and heatmap captures in progress, deletes the tracker’s IDs, groups and capture markers, removes the _ccid it added to links, and stops all tracking. It remembers the choice (cco) so it holds on later page loads on this hostname, and other open tabs on the same hostname stop too.

optIn

js
clickclacks('optIn')            // or clickclacks.optIn()

Forgets the opt-out and resumes tracking with new IDs. Counts the current page if it wasn’t counted yet. In opt-in mode this is the call that starts tracking, and it applies to the current tab only. It does nothing while data-respect-gpc="on" and the browser sends Global Privacy Control. Guide: Consent and opt-out.

The call queue

If window.clickclacks.q is an array when the tracker starts, each entry (an arguments list) is replayed in order, before the first pageview. That lets you call the tracker before it has loaded:

html
<script>
  window.clickclacks = window.clickclacks || function () {
    (window.clickclacks.q = window.clickclacks.q || []).push(arguments)
  }
</script>

Browser storage

No cookies. Everything is in the page’s own origin, so each hostname has its own copy.

KeyWhereHolds
ccplocalStorageThe browser’s anonymous ID, per_ + 32 hex characters.
ccilocalStorageThe ID passed to identify.
ccglocalStorageThe groups set with group, one ID per group type.
ccolocalStorage1 while the visitor is opted out.
_cc_caplocalStorageMarkers for heatmap captures already taken from this browser.
ccssessionStorageThe session ID, ses_ + 32 hex characters.
cclsessionStorageWhen the session was last active. After 30 minutes without an event, the next one starts a new session.
ccc<key>sessionStorageThe source’s heatmap and click-capture settings, cached for the tab.

Network requests

RequestWhat for
GET /c.jsThe tracker, from app.clickclacks.io or your custom domain.
POST /api/ingest?key=…Event batches, to app.clickclacks.io. On a custom domain: POST /e?key=…. Sent as text/plain JSON, without credentials.
GET /api/heatmap-config?key=…The source’s capture and click settings, to app.clickclacks.io. Cached for the tab session, and asked again only on pages that may still need a capture.
GET /heatmap-screenshot.jsOnly when this browser is asked to take a heatmap capture, from the same origin as c.js.
POST /api/heatmap-capture?key=…A masked heatmap capture, to app.clickclacks.io.

Events are batched: sent every 5 seconds, as soon as 25 are waiting, and when the page is hidden or closed. A failed batch is kept and retried with the next one, up to 100 waiting events.

Browser support

The tracker is a small ES5 script with no dependencies. It needs URL, localStorage and sessionStorage, which every current browser has. It sends with fetch and keepalive, falling back to sendBeacon. Where storage is blocked it stays off rather than break your page.