Événements suivis
Une consultation de page indique quelle page a été ouverte. Elle n’indique pas si le lecteur a copié l’extrait, interrogé l’assistant, fait défiler la page au-delà de l’introduction ou quitté la page pour accéder à votre page d’inscription. Cette page constitue la liste complète de tout ce qui est également enregistré, champ par champ, afin que vous puissiez vérifier, avant de créer un objectif ou un entonnoir, si l’élément que vous souhaitez mesurer est déjà suivi.
Ce que vous obtenez#
Trente-six événements docs.* nommés, répartis en sept catégories, enregistrés sur chaque
site de documentation sans configuration ni gestionnaire de balises. Chacun d’eux constitue une ligne
que vous pouvez filtrer dans les flux, associer à un objectif,
classer dans la vue d’ensemble des analyses, ou consulter à nouveau pour chaque
visiteur via MCP.
Leur enregistrement ne coûte rien sur le solde de votre projet, et la liste ne change pas selon votre forfait.
Le catalogue#
Chaque événement contient le nom complet de votre projet (owner/repo). La colonne Contient également indique ce qu’il ajoute à cela. Les événements marqués balise sont transmis par navigator.sendBeacon au moment où le lecteur quitte la page ; les autres utilisent le transport de journalisation ordinaire, qui regroupe les événements pendant deux secondes.
Assistant IA#
| Événement | Se déclenche lorsque | Contient également |
|---|---|---|
docs.ai_open |
Le lecteur ouvre le panneau de l’assistant | conversation_id |
docs.ai_query |
Une question est envoyée | question, answer, conversation_id, turn |
docs.ai_like / docs.ai_dislike |
Un pouce est attribué à une réponse | path, conversation_id, question |
docs.ai_copy |
Une réponse est copiée | conversation_id |
docs.ai_navigate |
Un lien cité par la réponse est cliqué | query, path, conversation_id, source (badge ou sources) — balise |
docs.ai_outbound |
Un lien dans la réponse redirige le lecteur hors de votre site | href, host, conversation_id, question — balise |
docs.ai_conversation |
Une fois par conversation, lorsque sa première réponse réussie reçoit un titre | topic, intent, competitor, question, answer_completeness, gap_type |
docs.ask_ai_outline |
« Demander à l’IA » est sélectionné depuis le plan de la page | — |
docs.ai_navigate et docs.ai_outbound sont délibérément deux événements, et non un seul.
Le premier indique que le lecteur a suffisamment fait confiance à la réponse pour ouvrir la page qu’elle citait ;
le second indique que l’assistant l’a redirigé vers votre application, votre dépôt ou un tout autre endroit — une question commerciale, et non de compréhension.
Recherche#
| Événement | Se produit lorsque | Contient également |
|---|---|---|
docs.search_open |
La boîte de recherche sur la page est ouverte | — |
docs.search_navigate |
Un résultat de recherche est sélectionné | query, path |
docs.search_no_result |
Une requête ne renvoie aucun résultat | query |
Lecture et engagement#
| Événement | Se déclenche lorsque | Transporte également |
|---|---|---|
docs.pageview |
Une page est servie | path, lang, trafficType, referrer, userAgent, source, ainsi que le pays, la région, la ville et les coordonnées déterminés par le point de présence |
docs.read_time |
Le lecteur quitte une page | path, seconds — balise |
docs.heading_view |
Un titre défile pour devenir visible | path, heading (en tant que #anchor) — balise |
docs.scroll_to_top |
Le bouton de retour en haut est utilisé | — |
docs.widget_toggle |
Un widget de contenu est ouvert ou fermé | widget, enabled |
docs.theme_toggle |
Le mode clair/sombre est activé | theme |
docs.language_switch |
Le sélecteur de langue est utilisé | from, to |
docs.pageview est le seul événement que le navigateur n'envoie pas. Il est écrit
côté serveur, et existe donc pour les lecteurs ayant désactivé JavaScript — c'est aussi
pourquoi une visite composée uniquement de pages vues est considérée comme celle d'un robot d'exploration. Sur les pages
servies depuis le cache, la page vue est envoyée par balise depuis le navigateur à la place, et le point d'ingestion
renseigne la même adresse IP et la même géographie, de sorte que les deux chemins
produisent la même ligne.
seconds est émis à l'état brut et limité à 300 secondes avant que les rapports n'en fassent la somme.
Cette limite, ainsi que sa raison d'être, sont expliquées dans le temps de lecture.
Actions sur le contenu#
| Événement | Se déclenche lorsque | Transporte également |
|---|---|---|
docs.copy_code |
Un bloc de code est copié | — |
docs.copy_page |
La page entière est copiée | — |
docs.copy_markdown |
La page est copiée au format Markdown | — |
docs.copy_dropdown |
Le menu de copie est utilisé | action |
docs.edit_on_github |
« Modifier sur GitHub » est cliqué | path |
Navigation#
| Événement | Se déclenche lorsque | Transporte également |
|---|---|---|
docs.sidebar_nav |
Une entrée de la barre latérale est sélectionnée | path |
docs.heading_nav |
Une entrée du plan de la page est sélectionnée | heading, path |
docs.page_nav |
Précédent/suivant est utilisé | direction (prev ou next), path |
docs.internal_link |
Un lien dans la page vers une autre de vos pages est sélectionné | href |
docs.heading_nav et docs.heading_view partagent volontairement le format #anchor afin qu’une section agrège les mêmes éléments, que les lecteurs y accèdent en cliquant dessus ou en faisant défiler la page jusqu’à elle.
Sorties et sources#
| Événement | Se déclenche lorsque | Contient également |
|---|---|---|
docs.outbound_link |
Un lien quitte votre documentation | href, host, path — balise |
docs.header_link |
Un lien dans l’en-tête de votre site est cliqué | label, href |
docs.utm |
Une visite arrive avec des balises de campagne | les paramètres utm_* tels quels |
docs.page_exit |
Le lecteur quitte le site ou recharge la page | path — balise |
docs.claim_banner_seen |
La bannière de publication/revendication est affichée | claim_token |
docs.claim_click |
La bannière de publication/revendication est cliquée | claim_token — balise |
docs.page_exit se déclenche uniquement lors d’une véritable sortie ou d’un rechargement. La navigation sur le site n’en produit pas, ce qui fait du dernier docs.page_exit d’une visite la page depuis laquelle le lecteur est réellement parti.
Commentaires#
| Événement | Se déclenche lorsque | Contient également |
|---|---|---|
docs.page_feedback_up |
Une page est jugée utile | path, pays |
docs.page_feedback_down |
Une page est jugée inutile | path, pays |
La direction est indiquée dans le nom de l’événement, et non dans un champ vote : le schéma du magasin
d’événements est un ensemble fixe de noms de champs, et un champ non reconnu est
entièrement rejeté plutôt que supprimé. Les votes sont enregistrés via une route
serveur afin qu’un webhook puisse être déclenché ; si cette requête échoue, le navigateur enregistre
directement le même événement, de sorte que le compteur est préservé.
Automatique ou dépendant d'une fonctionnalité#
Il n'y a aucun bouton de suivi nulle part dans Docsbook, ni indicateur enabled sur aucun
événement. Chaque événement ci-dessus est émis dès lors que l'élément qui le produit existe,
ce qui divise la liste en deux :
| Toujours | Seulement une fois que la fonctionnalité est utilisée |
|---|---|
| Pages vues, temps de lecture, vues des titres, sorties, copies, liens internes et sortants, navigation dans la barre latérale et navigation précédent/suivant, recherche, thème, retour en haut de page | Chaque événement docs.ai_* (nécessite l'assistant destiné aux lecteurs, qui est une fonctionnalité payante — voir les tarifs), docs.language_switch (nécessite une deuxième langue), docs.edit_on_github (nécessite un dépôt lié), docs.utm (nécessite des liens que vous avez vous-même balisés), docs.widget_toggle (nécessite un widget sur la page), la paire de retours (nécessite le widget de vote), les deux événements docs.claim_* (uniquement sur un site non revendiqué) |
Un événement « vide » dans vos rapports peut donc avoir deux interprétations, et elles sont différentes : personne ne l'a fait, ou rien ne peut encore le faire.
Comment il est transmis#
Les événements ordinaires passent par un transport qui les regroupe pendant deux secondes et les envoie
via fetch. Cela convient pour un clic qui laisse la page ouverte, mais
tout est perdu pour un clic qui ne la laisse pas ouverte — c’est pourquoi les événements liés
au départ suivent une seconde voie :
- Les composants enregistrent un collecteur de sortie. Lors de
pagehide, chaque collecteur est vidé dans un seul beacon, limité à 100 événements, envoyé à un point de terminaison de même origine. - Sur iOS,
visibilitychange → hiddendéclenche le même vidage, carpagehiden’y est pas fiable. - Les collecteurs renvoient uniquement ce qu’ils n’ont pas déjà envoyé, de sorte qu’un vidage iOS suivi d’un véritable départ ne compte pas deux fois les événements, et qu’une page restaurée depuis le cache arrière/avant puisse effectuer un nouveau vidage.
Les vues des titres sont collectées avec un IntersectionObserver à un seuil de 0 et une
marge inférieure de -15%, et chaque titre cesse d’être observé une fois vu : un titre
est comptabilisé une fois par affichage de page, et uniquement après avoir dépassé le bas de la fenêtre d’affichage,
plutôt qu’au moment où il y apparaît.
Pourquoi c’est la bonne méthode#
| Règle | Pourquoi cela fonctionne dans le navigateur qui l’exécute | Source |
|---|---|---|
Les événements au moment de la sortie sont envoyés par beacon, jamais via un fetch avec temporisation |
Les requêtes beacon sont « garanties d’être initiées avant le déchargement de la page et sont autorisées à s’exécuter jusqu’à leur terme sans nécessiter de requêtes bloquantes » | API Beacon du W3C |
| Ne bloquez pas la sortie pour envoyer l’événement | Les alternatives auxquelles la spécification Beacon répondait — « effectuer des requêtes bloquantes via des XMLHttpRequest synchrones, insérer des boucles d’attente actives ne faisant rien » — « empêchent l’agent utilisateur d’exécuter des opérations urgentes … et nuisent à l’expérience utilisateur » | API Beacon du W3C |
Écoutez pagehide, et également lors d’un changement de visibilité |
unload « reste peu fiable, évitez donc de l’utiliser sauf en cas d’absolue nécessité » ; pagehide « se déclenche dans tous les cas où l’événement unload se déclenche » et également lors de l’entrée dans le cache bfcache |
web.dev : bfcache |
Détectez l’affichage des titres avec IntersectionObserver, et non avec un gestionnaire de défilement |
Le calcul de position par requête DOM est « connu pour provoquer une recalcul (coûteux) des styles et de la mise en page », et les sites qui « abusent des gestionnaires de défilement » provoquent des « saccades lors du défilement » ; la transmission asynchrone « élimine la nécessité de requêtes DOM et de styles coûteuses, ainsi que d’un sondage continu » | Intersection Observer du W3C |
Comptez un titre une fois qu’il a franchi la limite de la fenêtre d’affichage, en utilisant rootMargin |
rootMargin applique des « décalages … qui agrandissent ou réduisent effectivement la boîte utilisée pour calculer les intersections » — la manière honnête de dire « effectivement atteint », et non « techniquement recouvert » |
Intersection Observer du W3C |
| Une page qui continue à compter lorsqu’elle est masquée mesure la mauvaise chose | L’API Page Visibility existe parce que « les développeurs web ont conçu des pages web comme si elles étaient toujours visibles » | Niveau 2 de l’API Page Visibility du W3C |
Comment lire les événements d'un visiteur#
Deux outils MCP permettent de reconstituer le parcours complet d'un visiteur
anonyme, et il s'agit dans les deux cas de lectures : get_top_visitors répertorie
les visiteurs les plus actifs sur une période, get_visitor_activity renvoie les
événements d'un visiteur dans l'ordre.
get_top_visitors(period: "7d", limit: 25)
→ [{ visitor_id: "a1b2…", pageview_count: 14, first_seen, last_seen, country }, …]
get_visitor_activity(visitor_id: "a1b2…", period: "7d")
→ { first_seen, last_seen, country, language, pageview_count,
events: [
{ event: "docs.pageview", at, path: "guides/quick-start" },
{ event: "docs.page_feedback_down", at, path: "guides/quick-start" },
{ event: "docs.search_no_result", at, query: "rotate api key" },
… ] }visitor_id est un hachage salé de l'adresse IP du lecteur, limité à votre
projet ; les adresses IP brutes ne sont jamais renvoyées. Consultez
comment fonctionne la mesure.
Limites et questions ouvertes#
- Aucun webhook ne peut se déclencher lors d’un événement
docs.*. Ces événements résident dans l’entrepôt d’événements, et rien ne les distribue. Ils peuvent être filtrés dans Feeds et enregistrés dans une liste, où ils apparaissent commenot_sentparce que c’est ce qu’ils sont. Les alertes sur le comportement des lecteurs passent par les événements webhook dérivés — baisse du trafic, recherche populaire, recherche sans résultat — et non par ce catalogue. Consultez les webhooks. - Les événements sont comptés par événement, et non par visite. Un lecteur qui copie cinq
extraits produit cinq lignes
docs.copy_code. Tout ce qui doit être compté par visite — un rebond, une conversion, un objectif — est dérivé en reconstituant la visite, et non en additionnant cette liste. - Un lecteur dont JavaScript est désactivé ne contribue qu’à
docs.pageview. Tous les autres événements ci-dessus nécessitent l’exécution d’un script, ce sur quoi repose précisément le filtre de l’explorateur comportemental. - Les champs
questionetanswercontiennent tout ce que le lecteur a saisi. Les données brutes des événements passent par un système de masquage qui masque tout champ dont la clé ou la valeur ressemble à un jeton, une clé, un JWT ou un en-tête d’autorisation, mais un lecteur qui saisit des informations personnelles dans votre assistant les a saisies dans votre entrepôt d’événements. La durée de conservation est de 30 jours. - Question en suspens : le catalogue fait autorité, mais ne recense pas exhaustivement le
flux. Ce qui est vérifiable, c’est que ces 36 noms sont ceux que chaque interface — le panneau,
Feeds, la validation des objectifs, MCP — lit à partir d’une liste partagée, de sorte qu’un objectif
ne peut être déclaré que sur un nom qui y figure. En revanche, quelques
noms
docs.*supplémentaires sont émis par le flux d’aperçu des sites non revendiqués et ne figurent pas dans cette liste, ce qui signifie qu’ils atteignent l’entrepôt et sont invisibles dans l’interface utilisateur. Considérez les 36 comme l’ensemble complet des événements sur lesquels vous pouvez agir, et non comme un inventaire complet de chaque chaîne présente dans le flux.
Pages connexes#
- Fonctionnement de la mesure — identité des visiteurs, filtrage des robots, conservation et confidentialité pour tout ce qui figure sur cette page
- Vue d’ensemble des analyses — les cartes et chiffres alimentés par ces événements
- Objectifs et entonnoirs — déclarer un résultat pour l’un de ces noms d’événements
- Temps de lecture —
docs.read_timecomme rapport - Webhooks — les événements susceptibles de vous avertir