Tracking

Most signal is captured automatically. This page covers the JavaScript API for the events only you can name - signups, purchases, feature usage - plus every automatic event, the script options, and the privacy controls.

The JavaScript API

The snippet exposes window.analytics on every page:

Custom events
analytics.track("signup_completed", {
  plan: "professional",
  source: "pricing",
});

// properties: string | number | boolean | null
// limits: name ≤ 100 chars · ≤ 30 properties · strings ≤ 500 chars
Identity (optional - no email required)
// after your app authenticates the user:
analytics.identify("internal-user-id");

// visitor-level properties for later segmentation:
analytics.set({ tier: "beta" });
Manual pageview + privacy
analytics.page();     // manual pageview (rarely needed - SPAs are automatic)
analytics.optOut();   // stop tracking this browser + clear its ids
analytics.optIn();    // resume
Call track() at the moment the thing actually happens - on the server-verified success callback, not on the button click. "signup_completed" should mean the signup completed.

Automatic events

These are collected without any code (each toggleable in Settings → Tracking). Names starting with $ are reserved:

EventWhat it means
$pageviewPage load or SPA route change (hash changes ignored unless enabled)
$scrollScroll depth thresholds 25/50/75/90/100 - once per pageview
$clickClicks on interactive elements, with a stable element descriptor and heatmap coordinates
$rage_click3+ clicks within ~1s in a ~50px radius - user frustration
$dead_clickA click with no observable consequence (no navigation, DOM change, network, focus) - heuristic, with a confidence level
$quickbackVisited a page and returned within 10s - content/UX quality signal
$outbound / $downloadExternal link clicks and file downloads
$form_start / $form_submitFirst input into a form / form submission (never the field contents)
$error / $resource_errorJavaScript exceptions (fingerprinted into issues) and failed scripts/styles/images
$web_vitalReal-user LCP, INP, CLS, FCP, TTFB with ratings
$copy / $media_play / $media_pause / $search / $404Text copied (length only), media interactions, internal search terms, 404 pages

For stable click identity across redesigns, tag important elements yourself - this always wins over generated descriptions:

<button data-analytics-id="hero-signup">Start free</button>

Goals & conversions

A goal turns an event or a page visit into a conversion. Create them in Settings → Goals: values starting with / match pages (append * for prefixes, e.g. /thanks/*); anything else matches a custom event name (e.g. signup_completed). Sessions containing a goal are marked converted everywhere - Overview, sources, funnels, session explorer, the "Why?" engine.

Script options

AttributeEffect
data-hash-routing="true"Treat #hash changes as pageviews (hash routers)
data-cookieless="true"No persistent visitor id - returning visitors are not linkable across visits
data-respect-dnt="true"Never track browsers with Do Not Track / Global Privacy Control
data-autocapture="false"Disable click/form/media autocapture
data-scroll="false"Disable scroll tracking
data-errors="false"Disable error capture
data-strip-params="coupon,ref"Extra query params to strip from URLs before sending

Server-side settings (sampling, replay, network telemetry, exclusions) live in Settings → Tracking and Settings → Privacy - the tracker fetches them at load, so changes apply without touching your site.

Privacy controls

Always on: anonymous random visitor ids scoped to one site, no fingerprinting, raw IPs discarded after coarse geolocation, sensitive URL parameters (token, email, code, session…) stripped both client- and server-side, and URL fragments never stored.

Session replay masks passwords and all input values before anything leaves the browser. Mark your own sensitive regions:

<div data-analytics-mask>   masked text (shown as ***)   </div>
<div data-analytics-block>  never serialized at all      </div>
<div data-analytics-ignore> input events ignored          </div>

Excluding your own visits

Testing your own site constantly? Two ways to keep yourself out of the numbers (Settings → Privacy):

1 · Browser flag (recommended) - open your site once with ?sp_ignore=true appended, e.g. https://yoursite.com/?sp_ignore=true. That browser is permanently excluded for that site - it survives IP changes, works at home, on café wifi, anywhere. ?sp_ignore=false re-includes it. Do it once per browser and device you test with.

2 · IP exclusion - add your home/office IPs (exact, or prefixes like 85.34.12.*) in Settings → Privacy; the page shows your current IP with one click to copy it in. IPs are compared at ingestion and immediately discarded - they are never stored. Excluded traffic shows up as a counter on the Installation page so you can confirm it's working.

Data deletion (whole site, everything, or a single visitor) lives in Settings → General; retention windows for raw events and replays in Settings → Privacy and → Tracking. Next: learn to read the dashboard.