What a tiny tracker actually does
A plain-English walk through Crustat's tracking script, under 2 KB: what it sends, when, and what it never does.
27 September 2026 · 4 min read
Crustat’s entire tracking script is under 2 KB. That’s small enough to read start to finish in a few minutes, so let’s do that. No black boxes, no “trust us,” just what the code does, in plain words.
It finds its own script tag
The very first thing it does is look at document.currentScript, which is the <script> tag that’s currently executing, meaning itself. From that tag, it reads its own src attribute, the full URL it was loaded from. That’s how it knows where to send data later, without you hardcoding the API URL yourself. Your site id comes from the data-site attribute on that same tag, the one you copied from your dashboard; without it, the script sends nothing at all. If the script tag gets rewritten or deferred in a way that breaks this lookup (some script-combining tools do that), the tracker simply has nothing to send to, which is why those tools need a small exclusion, covered in our docs on Rocket Loader and script combiners.
It checks if it should even run
Before doing anything else, it checks the page’s hostname against localhost, 127.0.0.1, and [::1]. If it matches, the script stops right there, so your local development doesn’t pollute your real visitor numbers.
Then it checks one flag, crustat_ignore, which a site owner can set on their own browser to leave their own visits out. If it’s set, the script stops too. It’s set only when the owner opens their site with #crustat-ignore at the end of the address (the dashboard has a switch that does it), and cleared with #crustat-ignore-off. That flag is the only thing the script ever writes, and only on that request. Your visitors never get anything stored.
It builds a small payload
For a pageview, the script gathers your site id, the current page’s full URL, where the visitor came from, and the browser window’s width. On the first view that’s the referrer the browser reports; in a single-page app, later views send the page the visitor was on before, so Crustat knows they’re still on your site. If the browser says it’s being driven by automation software, the event carries a small flag so the server can set it aside.
It sends it, carefully
The script uses navigator.sendBeacon, a browser API built for exactly this kind of “fire and forget” call: it queues the data even if the page is about to close, and doesn’t block or delay anything else on the page. If sendBeacon isn’t available or refuses, it falls back to fetch with the keepalive flag, which behaves much the same. It never waits for an answer, and any error is swallowed quietly.
The data is sent as plain text, not JSON with special headers, which avoids a CORS preflight request: one less round trip before the real request goes out.
It listens for client-side navigation
For single-page apps that change the URL without a full page reload, the script wraps the browser’s history.pushState function and also listens for the popstate event (back and forward navigation). Each time either fires, it checks: did the path or query string actually change? If yes, it sends another pageview. If not, meaning it was just an anchor jump or a redundant same-URL push, it does nothing.
It notes how long a page was looked at
When the tab goes to the background or the page closes, the script sends one small “leave” event with the whole seconds the page was actually visible, capped at half an hour. Time spent in a background tab doesn’t count. It also says whether the visitor touched the page at all (a click, a key, a scroll), as a yes or no, never what or where. In a single-page app, moving to a new page sends the previous page’s leave first.
It notices links to other sites
One click listener watches for clicks on links that go to another website, plus mailto: and tel: links. When one is clicked, the script sends the link’s address, without its query string or anything after a #. It never holds up the click: the visitor goes where they were going straight away.
What’s not in there
No cookie is set, and nothing is stored on a visitor’s device: no localStorage entry, no visitor id. The server counts unique visitors with an anonymous code that changes every day. No form fields are read, nothing about what’s typed, no mouse movements, no scroll depth. No fingerprinting technique tries to identify the device beyond what’s already sent. No request goes anywhere except to Crustat’s own API. And nothing runs on a timer: there’s no heartbeat, so a page that just sits open sends nothing.
That’s the whole thing: under 2 KB of plain JavaScript doing exactly what’s described above and nothing more.