Tracker API

Everything the browser tracker understands: the attributes on its script tag and the five 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"></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-queryOptionaloff sends page paths and campaign data without the query string.
data-captureOptionaloff stops heatmap captures from this page. Events are unaffected.
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.
  • 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.

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.

reset

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

Forgets the identified ID, 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, deletes the tracker’s IDs, stops all tracking, and remembers the choice (cco) so it holds on later page loads on this hostname.

optIn

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

Forgets the opt-out and resumes tracking with new IDs. Counts the current page if the opt-out stopped it being counted. 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.
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.