Skip to content

Advanced tracking

Every option here is set as a data-* attribute on the loader tag. The defaults are tuned for most sites, so reach for these only when you need the specific behavior.

data-spa is on by default. The tracker listens to History API navigations and hashchange and fires a pageview on each route change, so single-page apps are covered without extra code.

SPA tracking (default)
<script defer src="https://cdn.statskit.ai/v.js" data-site-id="vpk_live_…" data-spa="on"></script>

For views that are not real navigations (modals, wizard steps), fire them yourself with statskit.page(path). Set data-spa="off" only if you want to take full manual control of pageviews.

data-mode="cookieless" stores ids in sessionStorage only and rotates the visitor id roughly every 24 hours. It avoids persistent first-party storage, which is the usual trigger for a consent banner.

Cookieless
<script defer src="https://cdn.statskit.ai/v.js" data-site-id="vpk_live_…" data-mode="cookieless"></script>

The default (persistent) mode keeps statskit_visitor_id as a stable UUID and statskit_session_id rolling after 30 minutes of inactivity. See identity for the full model.

Route events through your own domain to resist ad-blockers and third-party-storage limits. Set data-proxy to a path prefix, then forward that path from your server to the StatsKit edge.

Proxy through /_v
<script defer src="https://cdn.statskit.ai/v.js" data-site-id="vpk_live_…" data-proxy="/_v"></script>

With data-proxy="/_v", the tracker posts events to /_v/e on your own origin. Your server forwards that request to https://edge.statskit.ai. Because the request is same-origin, ad-blockers that key on third-party domains do not see it.

data-respect-dnt is off by default. Turn it on to make the tracker do nothing when the browser signals Do-Not-Track (DNT) or Global Privacy Control (GPC):

Honor DNT / GPC
<script defer src="https://cdn.statskit.ai/v.js" data-site-id="vpk_live_…" data-respect-dnt="on"></script>

When the signal is present, the tracker collects and sends nothing for that visitor.

Events are buffered and flushed in batches rather than one request per event. Three attributes tune this:

AttributeDefaultEffect
data-flush5000Flush interval in milliseconds.
data-batch20Flush as soon as this many events are buffered.
data-max-buffer1000Hard cap on buffered events. On overflow the oldest are dropped.
Tuned batching
<script defer src="https://cdn.statskit.ai/v.js"
data-site-id="vpk_live_…"
data-flush="3000"
data-batch="10"
data-max-buffer="500"></script>

The tracker also flushes on visibilitychange to hidden and on pagehide, using navigator.sendBeacon with a fetch(keepalive) fallback so events are not lost on unload. Failed batches retry with capped exponential backoff and honor 429 / Retry-After. Each event carries a UUID for server-side dedup, so a retried batch is not double-counted.