veilletech.fr
21 sept. Feed du jour
#04 WEB Article

Sur 2 000 visites par jour, moins de 200 humains

Une audience mesurée dans les logs compte aussi les robots, et ils sont désormais plus nombreux que les lecteurs.

Vincent Bernat a remplacé l'analyse de ses logs par GoatCounter, avec un client JavaScript qui n'enregistre une visite qu'après une interaction réelle. Ses visiteurs quotidiens passent d'environ 2 000 à moins de 200 : l'écart est fait de robots d'aspiration pour l'IA, que les filtres classiques ne détectent plus.

2 min de lectureintermédiairevidéo 1:17
Partager
Sommaire5 sections
  1. Ce qui se passe
  2. Le filtre : attendre un geste
  3. Pourquoi GoatCounter
  4. Les limites
  5. À retenir

Ce qui se passe

Vincent Bernat a retiré Google Analytics de son blog en 2016 et suivait depuis son audience avec GoAccess, qui lit les journaux du serveur. Depuis deux ans, les chiffres ne voulaient plus rien dire : les robots qui aspirent le web pour l'IA, passés par des proxys résidentiels et munis de user agents usurpés, portaient le compte à environ 2 000 visiteurs par jour. Avec GoatCounter et un client JavaScript de sa main, il compte désormais moins de 200 humains par jour.

Le filtre : attendre un geste

L'idée vient de Bear Blog. La visite n'est envoyée qu'au premier geste du lecteur — touchmove, mousemove, keydown ou pointerdown —, une seule fois. Un robot qui récupère le HTML sans lancer de navigateur ne produit aucun de ces événements. Googlebot, qui exécute le JavaScript dans un Chromium sans interface, n'interagit pas non plus avec la page.

Le principe, réduit à l'essentiel :

JavaScript
const events = ['touchmove', 'mousemove', 'keydown', 'pointerdown'];

function recordVisit() {
  events.forEach((name) => document.removeEventListener(name, recordVisit));
  const url = `/count?p=${encodeURIComponent(location.pathname)}`;
  // A lost hit must not bother the reader, but it should stay visible in the console.
  fetch(url, { keepalive: true }).catch((err) => console.debug('visit not recorded', err));
}

events.forEach((name) => document.addEventListener(name, recordVisit, { passive: true }));

Pour les lecteurs sans JavaScript, environ 2 %, une règle CSS sur body:hover charge une image de comptage via border-image : le survol tient lieu de geste.

Pourquoi GoatCounter

Un binaire unique et une base SQLite. Ni cookie ni adresse IP stockée : la session est un identifiant valable 8 heures, dérivé du user agent et de l'IP. L'auteur cite comme alternatives, de la plus simple à la plus lourde, Umami, Plausible et Rybbit.

Le reste de l'article détaille son déploiement : un proxy local sur chacun de ses 5 serveurs, qui garde les visites en mémoire et les transmet par lots à l'API /api/v0/count (proposé en amont dans la PR #909, que le mainteneur a refusée) ; des conteneurs systemd-nspawn éphémères sous NixOS, déployés avec Colmena ; une réplication continue de la base par Litestream vers un stockage SFTP.

Les limites

C'est la mesure d'un seul blog, en accès libre. L'auteur suppose que les robots ne lancent pas de navigateur complet quand le contenu est accessible sans obstacle ; un robot qui simule des gestes passerait le filtre. Il sert aussi le point de comptage sur le domaine du blog, ce qui contourne les bloqueurs de publicité — un choix qu'il assume parce que l'outil ne collecte pas de données personnelles.

Source : Bot-free self-hosted analytics with GoatCounter on NixOS, Vincent Bernat, 20 septembre 2026.