Script tag
One line in your HTML. Works on every platform, including the ones that will not let you run a build step.
<script
defer
data-site="tkb_a1b2c3d4"
data-domain="example.com"
src="https://stats.example.com/js/tkb_a1b2c3d4.js">
</script>Put it in <head> if you can, or anywhere in <body>. defer means it never
delays your page.
Single-page apps
Route changes are counted automatically: trckable listens for pushState,
replaceState and popstate, and counts a page when the path or the query
string changes. The same URL pushed twice is not two pageviews, which is what
most frameworks do on every render.
Hash routes (#/pricing) are not separate pages yet: the server keeps the
path before the #, so a hash-routed app shows as one page.
Calling it from your code
The script defines a global function. To be able to call it before the script has loaded, add the two-line stub above it:
<script>
window.trckable = window.trckable || function () { (window.trckable.q = window.trckable.q || []).push(arguments) }
</script>
<script
defer
data-site="tkb_a1b2c3d4"
data-domain="example.com"
src="https://stats.example.com/js/tkb_a1b2c3d4.js">
</script>Then:
trckable('goal', 'signup', { plan: 'pro' }) // count a goal, with properties
trckable('pageview') // count a page yourself
trckable('consent', true) // the visitor accepted cookiesSubdomains
A cookie set by a script on stats.example.com for a page on example.com is a
first-party cookie, but Safari caps script-set cookies at seven days. To share
one visitor across www.example.com and app.example.com, the cookie goes on
the parent domain: that is what data-domain="example.com" in the tag above
does. Keep it set to the site's domain.
To get past Safari's seven days entirely, serve events from your own origin — see the proxy.
A landing page here and a Next.js app on a subdomain: see Landing page and app.
Content Security Policy
If you send a CSP, allow the script and the events:
script-src 'self' https://stats.example.com;
connect-src 'self' https://stats.example.com;With a same-origin proxy, 'self' alone is enough.
Subresource Integrity
There is no integrity attribute for a per-site script, because its hash
changes whenever you turn a module on or off. Publishing one that goes stale
would break your analytics the first time you changed a setting, so trckable
does not offer one rather than offering a broken one.
Install
Three ways in — a script tag, the npm package, or your own server as a proxy. They record the same things; they differ in how much of your traffic survives an ad blocker.
npm package
One install with subpath exports for React, Next, any other framework and your server. The tracker is bundled into your own code, so there is no separate file for anything to block.