Skip to main content

LEGAL

Cookies & Analytics

How troykelly.com uses cookies (almost none) and measures traffic with cookieless, self-hosted, first-party analytics.

IN EFFECT

This page explains the two things people usually want to know about a website: what it stores in your browser, and how it counts visitors. The short version is that this site keeps almost nothing on your device and measures traffic without cookies. For the full picture of what personal information I collect and why, see my Privacy Policy.

Cookies on this site

The public site sets no advertising, marketing, or tracking cookies. There is no ad network, no cross-site tracking pixel, no social “like” button that phones home, and no analytics cookie.

On the pages any reader can visit, the site writes no Set-Cookie header. It does write a few small, first-party records to your browser’s localStorage and sessionStorage. They remember your Pictures / Text only choice and how the pictures and motion on the /story Show have been running on your device. None of them is ever transmitted to any server, sent to me, or shared with anyone.

localStorage (the browser has no expiry for it; it stays until overwritten, removed as described, or you clear it):

  • tk-show:choice holds script or show, the choice you made with the Pictures / Text only switch (on /story, or in the footer of the home and 404 pages). It is used to show you the version you chose, except that choosing Pictures cannot start them on a browser that cannot run them at all. It stays until you change it or clear your site data.
  • tk-show:strikes holds your browser’s User-Agent string and a short list (at most six) of recent tab sessions in which the /story pictures stepped down, each with a random session id, a timestamp and the level the page stepped down to (lighter pictures or text only). The site writes it each time the pictures step down, where the browser allows sessionStorage. It is used to start /story on text only when three of those sessions inside 30 days stepped down to text only, and on lighter pictures when three sessions of any kind did. The 30 days is only the period in which an entry counts towards that decision. It is not a deletion date. An entry older than 30 days is ignored, and the whole list is ignored if your User-Agent has changed. Such entries are dropped only when the record is next written. The site removes the whole record in two cases only. First, when you press Pictures on the /story switch while it shows Text only. Second, when, during one load of /story, the pictures run and pass six frame-rate checks that do not call for a step down, with no step down earlier in that load. That second case applies however the pictures came to run, including when you chose Pictures. The pictures do not run on /story when you have chosen Text only, or when your browser cannot run them at all, in which case the switch is not shown. Otherwise they run unless something holds the page on text: a reduced-motion, data-saver or reduced-data setting, a 2G connection, under 4 GB of memory, under four processor cores, graphics the site rates too low, this tab having already stepped down to text only, or, if this tab has not stepped down at all, three text-only entries in this record inside 30 days. Choosing Pictures overrides those holds. Nothing else removes the record. Choosing Text only, the footer switch on the home and 404 pages, and the passing of 30 days do not remove it. It stays until a later step down rewrites it or you clear your site data.
  • tk-show:hard holds your browser’s User-Agent string and a timestamp. Each time /story runs its check, the site writes it with a fresh timestamp if it finds that the pictures cannot run on your browser at all, and removes it if the check ends any other way, including when the page stays on text for another reason. It is read before /story first paints, to set the text up for a browser that cannot run the pictures. The site ignores it once it is more than 30 days old or if your User-Agent has changed, but it does not delete it then. It stays until the next /story check or until you clear your site data.
  • tk-show:paused holds 1 when you pause the motion on /story, and is removed when you resume it. It keeps the motion paused on later visits.

sessionStorage (kept for the browser tab session; the browser discards it when the tab is closed):

  • tk-show:session holds the level the page stepped down to in this tab and the time, written each time the pictures step down. It is used to keep that level for the rest of the tab session. It is also removed when you press Pictures on the /story switch while it shows Text only.
  • tk-show:sid holds a random id for this tab session, written the first time the pictures step down in that tab, so one session counts as at most one entry in tk-show:strikes.

You can remove all of these at any time by clearing your browser’s site data for troykelly.com. None of them is transmitted to any server.

There is also an administrative session cookie, but it is issued only when I sign in to the site’s private admin area — it is never set on the public reader pages you browse, so it does not touch ordinary visitors.

How I measure traffic

I want to know, roughly, which writing people read — but not who you are. To do that I run Plausible, a privacy-focused analytics tool, self-hosted (rather than a third-party analytics cloud). The instance runs on infrastructure operated by Aperim; where it is hosted is covered in my Privacy Policy.

Plausible is cookieless by design: it sets no cookie and creates no persistent visitor identifier. On this site it goes a step further. The analytics script and the endpoint that receives events are both served first-party, same-origin, through the site itself (/pa/js/script.js for the script and /pa/event for events). Because everything is proxied through this domain, your browser makes zero third-party requests for analytics — nothing loads from an external analytics domain. This is not just a claim: the site’s automated build quality gate checks that a typical page carries no third-party requests at all, with the only exception being a post that embeds media (see below).

Analytics runs only on the live production site. On staging, previews, and non-indexable utility pages, no analytics events are sent at all.

What the analytics derives

From those events, the analytics produces aggregate, non-identifying measurements:

  • counts of pageviews and events, and which pages and links they relate to;
  • a coarse country or region, inferred from your IP address at the time of the request; and
  • the general characteristics of the request, such as the browser or device type reported by your User-Agent.

Your IP address is used only transiently to derive that coarse geography — the site keeps no raw-IP record of visitors. To distinguish one visit from another within a single day without a cookie, Plausible’s design generates a salted hash that rotates daily and is then discarded, so there is no persistent, cross-day identifier for you. That daily-hash behaviour is a feature of Plausible’s own product design rather than something this site adds on top.

The result is a picture of how many people read what, not who read it.

Search analytics

The site has a search box at /writing/search. When you run a search there, the analytics records a Search event so I can understand what readers are looking for and whether they find it. That event includes:

  • the text of your search query, tidied up (extra whitespace collapsed) and trimmed to 120 characters; and
  • the number of results the search returned.

I want to be plain about this rather than bury it: the words you type into the search box are recorded against that analytics event. Please avoid typing anything sensitive or personal into the search field. Like all analytics on this site, the Search event is only sent on the live production site. There is more detail in my Privacy Policy.

You will not see a cookie consent banner on this site, and that is deliberate. A consent banner exists to obtain permission for non-essential cookies — advertising, tracking, and analytics cookies. This site sets none of those. The measurement is cookieless, and the only things stored in your browser are the first-party display-preference records listed above, which are not used to track you.

Because there are no non-essential cookies to consent to, there is nothing for a banner to ask about. If that ever changes — for example, if I introduced a technology that did require consent — I would update this page and put an appropriate consent mechanism in place first.

Third-party embeds

Most articles make no third-party requests at all. Some posts, though, embed media — a YouTube video, a Vimeo clip, or a SoundCloud track. When a page includes one of those embeds, your browser loads that provider’s player directly, and the provider may set its own cookies or storage inside its embedded frame. That happens under the provider’s own terms and privacy policy, not mine, and it only happens on the specific posts that embed their media.

Where YouTube is embedded, the site requests the privacy-enhanced youtube-nocookie player, and uses it whenever the provider returns it — though that is the provider’s choice, not something the site can guarantee.

The relevant terms for using this site, including how third-party content is treated, are in my Terms of Use.

Further choices

Because the measurement here is already cookieless and served first-party, there is little for a privacy signal to switch off. If your browser sends a Do-Not-Track or Global Privacy Control signal, no special handling is needed: this site does not set tracking cookies, does not build a cross-site profile, and keeps no persistent visitor identifier regardless of any such signal.

If you would like even less to load, a content blocker or your browser’s privacy settings can block the analytics script and any embedded media players; the site is designed to work without them. And if you have a question about any of this, please write to me at troy@troykelly.com.