Centralized analytics for brine.dev apps (brine, discover, rando...)
I got really tired of maintaining analytics in multiple apps, thus chalk was born.
- app decides scope: is this hit even worth sending (skip static assets, identify feed routes, etc.). Only the app knows its own routing.
- Chalk decides substance: is this a bot, a datacenter IP, mobile vs
desktop, an RSS aggregator. Judged the same way for every property, in one
place (
src/analytics-core.js), so a fix there fixes it everywhere at once.
cp wrangler.example.toml wrangler.tomlnpx wrangler d1 create chalk— paste thedatabase_idit gives you intowrangler.toml- Pick a
HIT_SECRETvalue and put it inwrangler.toml npx wrangler deploy- Visit
/login— it'll walk you through generatingAUTH_PUBKEYfrom a passphrase. Add that towrangler.tomland deploy again.
- Add a
HIT_SECRET-matching var to the new app'swrangler.toml(must match chalk's ownHIT_SECRET). - Fire a non-blocking
POSTtohttps://chalk.brine.dev/hiton real requests, with the shared secret and raw signal:
await fetch('https://chalk.brine.dev/hit', {
method: 'POST',
headers: { 'Content-Type': 'application/json', 'x-hit-secret': env.CHALK_HIT_SECRET },
body: JSON.stringify({
domain: env.DOMAIN_NAME, // required
path, // required — pathname + query string
ip, // required — req.headers.get('cf-connecting-ip')
ua: req.headers.get('user-agent') || '',
referrer, // only if cross-origin
country: req.cf?.country,
city: req.cf?.city,
region: req.cf?.region,
asn: req.cf?.asn,
rss_feed: rssFeedName, // string if this path is a feed, else omit
ts: Date.now()
})
}).catch(() => {})- Skip what you already know isn't worth tracking — static assets, health checks, internal routes.
.catch(() => {})on the fetch — a hit failing to send should never break the actual page request.