The open-source tracking snippet powering Statjot — privacy-first product analytics for indie hackers.
One script tag. No cookies. No localStorage. No fingerprinting. No PII ever leaves the browser.
- Tracks pageviews automatically, including SPAs (React, Next.js, Vue, Svelte)
- Tracks scroll depth per page
- Exposes a
statjot()API for custom events - Session ID lives in memory only — gone when the tab closes
- Respects
localStorage.setItem('statjot_ignore', 'true')to opt out
<script defer src="https://statjot.com/track.js" data-site="YOUR_PUBLIC_KEY"></script>Get your public key from statjot.com after creating a site.
// Track any user action
statjot('event', 'signup_complete')
// With properties
statjot('event', 'upgrade', { plan: 'indie', mrr: 9 })
statjot('event', 'cta_click', { button: 'get-started', location: 'hero' })
statjot('event', 'export_csv', { rows: 142 })The snippet automatically intercepts pushState and replaceState for SPA route changes. For Next.js App Router, add it to your root layout:
// app/layout.tsx
export default function RootLayout({ children }) {
return (
<html>
<head>
<script
defer
src="https://statjot.com/track.js"
data-site="YOUR_PUBLIC_KEY"
/>
</head>
<body>{children}</body>
</html>
)
}Point the snippet at your own ingest endpoint:
<script
defer
src="https://statjot.com/track.js"
data-site="YOUR_PUBLIC_KEY"
data-api="https://your-domain.com/api/ingest"
></script>| What most tools do | What this snippet does |
|---|---|
| Store a persistent cookie | No cookies, ever |
| Fingerprint browser/IP | Never |
| Send IP to server | IP used only for country lookup, never stored |
| Use localStorage for identity | Session ID in memory only |
| Track across tabs/sessions | Each tab is a fresh session |
No consent banner required in most jurisdictions. GDPR-compliant by design.
{
"type": "pageview" | "custom" | "scroll",
"url": "https://yoursite.com/pricing",
"referrer": "https://google.com",
"session_id": "<random, in-memory UUID>",
"properties": { ... },
"timestamp": "2026-05-18T09:00:00.000Z"
}
No IP address. No user agent beyond what the server already sees. No email. No name. Nothing that identifies a person.
npm install
npm run build # outputs track.jsMIT. Use it, fork it, self-host it.
Built by Daniel — solo founder shipping from Panama.