Privacy and analytics
Kartotek's optional, cookie-free visit analytics — what it measures, why it's designed the way it is, and how a site owner turns it on.
For visitors
If a Kartotek site has this feature enabled, viewing a Post or Category page counts as one aggregate page view — nothing more. There is no analytics cookie, tracking pixel, browser fingerprinting, or persistent identifier of any kind, on this or any Kartotek site. No IP address, User-Agent, referrer, or session identifier is ever stored — the only thing written down is a daily count of page views, per page, with nothing that could identify who made them.
Because nothing is read from or written to your own device, there's no consent banner — there's no cookie to consent to. The live, legally-binding notice for the specific site you're on (with its actual controller details filled in) is at that site's own /_privacy address, linked from this doc's own site's /_privacy.
For administrators
The admin sidebar's Analytics section shows: site-wide summary cards (total Post page views, total direct Category page views) for a selectable range (7/30/90/365 days, or all time) and Domain (all, a specific configured Domain, or the unconfigured/default bucket); a daily trend chart for each, with an accessible data table alongside it; a ranked table of the most-viewed Posts; and a ranked table of Categories showing direct and contained page views side by side. A Post's own admin page and a Category's own admin page each get a compact Analytics card with today/7-day/30-day/all-time totals and a link to the full overview. A collapsed Privacy and data panel explains what is and isn't stored and provides two irreversible deletion actions — delete everything, or delete everything before a chosen UTC date.
What counts as a page view: one successful, public (non-admin), Stage-eligible resolution of a Post or Category. A PrePub or Hidden Post, a request from a logged-in admin session, and a 404 never count. A reload counts again — there's deliberately no attempt to deduplicate repeat views. Known automated traffic (search crawlers, social/link-preview bots, uptime monitors, common headless-automation and HTTP-library User-Agents, and Kartotek's own PDF/JSON export generator) is excluded via a small, deterministic classifier — unknown automation may still be counted, which is why the dashboard describes page views as approximate rather than exact.
A Post's view rolls up into its directly-assigned Category's own counter and every ancestor Category above it, as the Category hierarchy is structured at the moment of that view — moving a Post or Category later only changes future counts, it never rewrites a day that's already been recorded. A Category's own page is counted separately from — and never combined with — the Posts assigned beneath it, so "direct Category page views" and "contained Post page views" always stay two distinct numbers.
For site owners: enabling and configuring analytics
Analytics defaults to disabled. Turning it on needs every one of the following set — any one missing keeps the feature off, and the admin Analytics page states exactly which are missing. Each is a database-backed setting managed from Admin → Settings (/_admin/settings) rather than only a deployment environment variable — the environment variable named alongside each one still works as a fallback/emergency override until an admin sets the field directly:
- Enable visit analytics (
ANALYTICS_ENABLED) — the master toggle. Turning it on from Settings requires typing an exact confirmation phrase, shown on the page, acknowledging you've reviewed this doc's legitimate-interest reasoning below — the same commitment theANALYTICS_LIA_ACKNOWLEDGEDenvironment variable used to represent on its own, now recorded automatically the moment you confirm. - Controller name (
ANALYTICS_CONTROLLER_NAME) — the controller's name, shown on the public/_privacynotice. - Controller email (
ANALYTICS_CONTROLLER_EMAIL) — a contact address, also shown publicly. - Controller country (
ANALYTICS_CONTROLLER_COUNTRY) — the controller's jurisdiction. - Supervisory authority URL (
ANALYTICS_SUPERVISORY_AUTHORITY_URL) — a link to the relevant data-protection supervisory authority. - Privacy contact (
ANALYTICS_PRIVACY_CONTACT) — optional, an additional contact/address line shown on the public notice.
Legal basis: this design's lawful basis is the controller's legitimate interest (GDPR Article 6(1)(f)) in understanding aggregate readership of its own published content, not consent — which is what makes the no-consent-banner design above correct, not an oversight. This is a technical privacy design, not a claim of legal certification for any jurisdiction: review the reasoning here and get your own jurisdiction-specific legal advice before enabling it in production.
Making the live notice discoverable: the visitor chrome doesn't carry a direct link to /_privacy in its footer — this doc, listed plainly in the /_docs/ sidebar, is the one deliberate route left to it. You remain responsible for judging whether that's sufficiently accessible for your own jurisdiction, and for adding a more prominent route (e.g. back in the page chrome) if your situation calls for it.
See also
Posts and publishing for the Post/Category model this measures, Domains, UIDs and addresses for Domains and UIDs, and Dashboard and maintenance for the admin dashboard generally.