About this project

sightings is a lightweight, cookieless pageview analytics library written in TypeScript. It tracks visits without writing anything to the user's device—no cookies, localStorage, or fingerprinting—and stores all rows directly in your own database. The design treats each visit as a "sighting": an observation that a visit occurred, not a record tied to any identity. Visitor identification uses a salted SHA-256 hash derived from IP, user agent, secret key, and UTC day, truncated to 128 bits and rotated daily. The library enforces strict data boundaries: query parameters outside the allowlist are rejected, referrer stores only hostnames, and there are no custom event payloads—adding any field to the beacon body returns a 400 error rather than recording a new metric. It distinguishes between two traffic halves that most tools conflate. Human visitors send a single `sendBeacon` request per navigation, counted server-side. Crawlers and AI agents (like gptbot, claudebot, perplexitybot, telegram-preview) never execute client-side JavaScript, so they are detected and counted in middleware using family-name classification rather than raw user-agent strings. This makes it practical to measure whether AI models have actually crawled your content. The core package runs anywhere a standard Request/Response pair and Web Crypto exist—Node, Deno, Bun, Vercel Edge, Cloudflare Workers. Official integrations include `@sightings/next` (Next.js App Router handler and middleware) and `@sightings/prisma` (Prisma adapter with schema model). Custom storage adapters can be implemented by providing a single `record()` method and optionally a `summary()` method. Key configuration options control the base API path, path-level redaction (e.g., dropping `/admin` and `/invite` subtrees), query-parameter allowlist (defaulting to `utm_*` and `ref`), crawler family detection, visitor hash window (daily by default, or hourly), IP and country header precedence, and error handling. A built-in `api.summary()` query interface provides aggregated views over date ranges with bot/human filtering. Direct recording methods are also exposed for SSR contexts, non-HTTP frameworks, or backfills. The repository uses changesets for lockstep versioning across its three packages and publishes provenance-linked tarballs via CI. Category: data | Subcategory: analytics-bi