Installer le script qm.js

La façon la plus simple de mesurer un site : un script de moins de 4 Ko compressé qui n'écrit chez vos visiteurs aucun identifiant, ni en cookie ni dans le localStorage. Deux écritures seulement sont possibles, et aucune ne distingue une personne d'une autre : le marqueur d'exclusion qm_ignore, que la personne pose elle-même pour ne plus être comptée, et le cookie de continuité de visite qm_visit, de dix minutes glissantes. Cette absence de cookie d'identification et de traçabilité ne garantit toutefois pas une exemption de consentement : chargez le script conformément aux finalités, aux fonctions activées et à la base légale que vous avez documentée.

Démarrage rapide

1. Récupérez votre clé de site. Dans votre espace membre, ouvrez Sites → votre site → Installation. Votre clé publique ressemble à qm_pub_XXXXXXXXXXXXXXXXX : elle est visible dans le HTML, c'est normal ; la clé secrète, elle, ne doit jamais apparaître côté navigateur.

2. Ajoutez le script. Copiez le fichier qm.js proposé sur l'écran d'installation à la racine de votre site. Servi par votre domaine, le tracking reste first-party et les listes de blocage par domaine sont inopérantes :

<script defer src="/qm.js" data-site="qm_pub_XXXXXXXXXXXXXXXXX"></script>

Le script déduit son endpoint de collecte de sa propre origine (…/qm.js…/collect). Servi depuis votre domaine, faites suivre les hits avec le proxy first-party ; sinon, chargez-le directement depuis la plateforme :

<script defer src="https://quietmetrics.dev/qm.js"
        data-site="qm_pub_XXXXXXXXXXXXXXXXX"
        data-endpoint="https://quietmetrics.dev/api/v1/collect"></script>

3. Vérifiez. L'écran d'installation vérifie en direct la réception du premier hit. Visitez votre site : la coche passe au vert.

Options du script

Attribut Rôle Défaut
data-site Clé publique du site (obligatoire : sans elle, le script ne fait rien) aucun
data-endpoint Endpoint de collecte explicite déduit de l'origine du script
data-spa Suivi des navigations SPA (pushState) true
data-outbound Suivi des clics vers des domaines externes activé ("false" pour couper)
data-downloads Événement « Téléchargement » au clic sur un lien de fichier désactivé ("true" pour activer)
data-404 Événement « 404 » avec le chemin demandé, à poser sur le gabarit d'erreur désactivé ("true" pour activer)

Applications monopage (SPA)

Par défaut, chaque history.pushState() déclenche une page vue : React Router, Vue Router, Inertia, Livewire… fonctionnent sans rien faire. Deux précisions :

  • Une navigation vers la même URL n'émet pas de doublon.
  • Le script se protège des doubles inclusions (window.__qmLoaded) : si votre bundler et votre layout l'injectent tous les deux, un seul compte.

Pour déclencher manuellement (routeur exotique, navigation par hash) : désactivez l'auto-suivi (data-spa="false") et appelez qm.pageview() après chaque navigation.

Événements personnalisés

<script>
  qm('inscription', { plan: 'pro', source: 'landing' });
</script>

Règles : nom ≤ 120 caractères, ≤ 30 propriétés scalaires (chaîne, nombre, booléen ; pas d'objet imbriqué), valeurs tronquées à 190 caractères. Évitez les valeurs à forte cardinalité (ID utilisateur, e-mail) : ce sont des données personnelles et elles saturent les agrégats.

Si le script n'est pas encore chargé, empilez sans risque :

<script>window.qm = window.qm || function () { (window.qm.q = window.qm.q || []).push(arguments); };</script>

Pour compter une conversion, créez l'objectif correspondant dans Sites → Objectifs : un objectif événement matche le nom exact ; un objectif page matche un chemin avec jokers (/merci, /docs/*).

Sans JavaScript : le pixel

Pour les contextes sans JS (e-mails, AMP, <noscript>), un GIF 1×1 compte une page vue :

<noscript><img src="https://quietmetrics.dev/p.gif?k=qm_pub_XXXXXXXXXXXXXXXXX&u=https%3A%2F%2Fmonsite.fr%2Fpage" alt=""></noscript>

Le pixel répond toujours 200 (jamais d'image cassée), le statut réel est porté par l'en-tête X-QM-Status.

Ne plus être compté : le marqueur d'exclusion

Une personne peut demander à ne plus être comptée sur votre site, sans compte et sans écrire à personne : elle charge n'importe quelle URL du site avec ?qm_ignore=1, et ?qm_ignore=0 la remet dans la mesure.

https://monsite.fr/?qm_ignore=1     ne plus être compté
https://monsite.fr/?qm_ignore=0     être compté à nouveau

Le marqueur est un cookie propriétaire de votre site, nommé qm_ignore et valant 1 (path=/, samesite=lax, secure en https, cinq ans), que qm.js double en localStorage. Deux stockages et non un : le cookie est le seul des deux qu'un SDK serveur sache lire, localStorage prend le relais là où le cookie est refusé ou effacé. Une seule visite couvre donc le script et le suivi serveur.

Il ne contient aucun identifiant, sa valeur étant la même chez tout le monde, il n'est jamais transmis à Quiet Metrics, et il n'existe que pour arrêter la mesure : c'est un marqueur de refus, pas un traceur. La visite qui le pose n'est pas comptée ; celle qui le retire l'est immédiatement.

C'est aussi le moyen le plus simple d'exclure vos propres visites, depuis n'importe quel navigateur. Les autres intégrations honorent le même marqueur sous le même nom : PHP, Laravel, Symfony et le plugin WordPress.

Le second, et dernier, écrit chez vos visiteurs. Il ne se confond pas avec le précédent : celui-là est demandé par la personne, celui-ci est posé par la mesure.

Il s'appelle qm_visit, il vaut 1, c'est un cookie propriétaire de votre site (path=/, samesite=lax, secure en https) dont l'expiration glisse de dix minutes et se rafraîchit à chaque hit. Aucune doublure localStorage, contrairement au marqueur d'exclusion.

Ce qu'il corrige : l'empreinte qui distingue vos visiteurs est recalculée à chaque hit depuis le réseau de l'abonné et le navigateur. Quand ce réseau change en cours de visite, typiquement au passage de la 4G au wifi, l'empreinte change avec lui et la même personne compte pour deux visiteurs uniques dans votre tableau de bord. Le cookie porte l'information qui manque : une visite est déjà en cours dans ce navigateur.

Il ne contient aucun identifiant, sa valeur étant la même chez tout le monde ; seule sa présence remonte, sous la forme de la clé c du payload de collecte. Et il n'est jamais posé chez un visiteur qui porte qm_ignore : le marqueur d'exclusion coupe la mesure avant toute écriture.

Servant la mesure et non l'enregistrement d'un refus, ce cookie ne bénéficie pas de l'exemption propre au marqueur d'exclusion : traitez-le comme le reste de votre configuration de mesure au regard de vos finalités et de votre base légale.

Cas particuliers

Content-Security-Policy. Copie locale : script-src 'self' suffit, et connect-src 'self' si le proxy first-party est sur le même domaine. Chargement direct depuis la plateforme : ajoutez https://quietmetrics.dev à script-src et connect-src.

Cache et CDN. La copie locale de qm.js se met en cache agressivement sans risque : le fichier est stable. Après une mise à jour du tracker, re-téléchargez la copie depuis l'écran d'installation (ajoutez ?v=2 à l'URL du script si votre CDN ignore les invalidations).

Plusieurs domaines. Un site peut déclarer des domaines supplémentaires (Sites → Domaines). La politique d'origine log (défaut) accepte tous les hôtes en les journalisant ; strict refuse (403) les hits dont l'URL ne correspond pas au domaine principal, à un domaine déclaré ou à leurs sous-domaines.

Exclure vos propres visites. Trois mécanismes : le marqueur d'exclusion ci-dessus (une visite sur ?qm_ignore=1, valable depuis n'importe quel navigateur), l'auto-exclusion propriétaire dans l'espace membre (votre navigateur est reconnu), ou window.__qmDisable = true posé par votre environnement (extension, staging, console).

Environnements de test. Créez un site séparé avec sa propre clé pour le staging, ou excluez ses chemins : ne polluez pas les statistiques de production.

Limites du chemin chaud

Le endpoint de collecte protège la plateforme : payload ≤ 4 Ko (400 au-delà), 60 hits/minute par IP et par site (429 au-delà), clé inconnue ou origine refusée → 403. Toutes ces réponses sont invisibles pour vos visiteurs : l'analytics ne casse jamais la page.

Les visiteurs sans JavaScript peuvent aussi être comptés côté serveur : voir SDK PHP, Laravel, Symfony ou le plugin WordPress.

Vous ne trouvez pas votre réponse ?

Le support répond en français, les jours ouvrés.