Aller au contenu
Pierre Bossetti

dataLayer

Audit & Plan de Taggage

Vos ventes GA4 ne correspondent pas à votre CRM ? J’audite votre tracking, je trouve ce qui le casse et je vous livre un plan de taggage clair, bâti sur du JS natif propre.

Pourquoi GA4 et votre CRM ne sont jamais d’accord

Vous ouvrez GA4. Il affiche 120 ventes ce mois-ci. Vous ouvrez votre CRM. Il en affiche 150. Lequel a raison ? En général, le CRM. GA4 perd des données, et vous ne savez pas combien.

Trois causes techniques expliquent l’essentiel de l’écart :

  • Les décalages de timing. GA4 enregistre une vente quand la page de remerciement se charge. Votre CRM l’enregistre quand le paiement est validé. Si le visiteur ferme l’onglet trop tôt, GA4 ne voit jamais la vente. Les remboursements et les ventes hors ligne ne parviennent jamais à GA4.
  • Les bloqueurs de publicité. Beaucoup de bloqueurs coupent la requête GA4 avant qu’elle ne quitte le navigateur. Le visiteur achète quand même. Votre CRM le voit. GA4 non.
  • Les paramètres perdus dans les redirections. Les clics publicitaires transportent des paramètres comme gclid etutm_source. Une mauvaise redirection (http vers https, www vers non-www, une étape de connexion) les supprime. La vente reste, mais sa source disparaît.

Cela compte, car vous pilotez votre budget avec ces chiffres. Si GA4 sous-compte un canal, vous le coupez. S’il en sur-compte un autre, vous le nourrissez. Vous dépensez plus sur ce qui a l’air bon et moins sur ce qui marche vraiment. La croissance cale, et personne ne sait pourquoi.

Les erreurs de tracking qui coûtent cher aux PME

Deux bugs reviennent sans cesse. Tous deux semblent mineurs. Tous deux coûtent de l’argent.

Événements dupliqués

Un événement purchase part deux fois. Causes fréquentes : un plugin et une balise GTM l’envoient tous les deux, ou le visiteur recharge la page de remerciement.

Google Ads et Meta utilisent ces événements pour apprendre qui sont vos meilleurs acheteurs. C’est le smart bidding. Si vous envoyez deux événements par vente, l’algorithme voit deux fois plus de conversions et apprend à partir des mauvais profils. Il enchérit sur les mauvaises personnes et votre coût par vente grimpe. La solution est simple : un seul événement par vente, avec untransaction_id unique.

Fuites d’attribution des passerelles de paiement

Votre client clique sur une annonce, choisit un produit et paie sur Stripe ou PayPal. Puis il revient sur votre site. GA4 voit une nouvelle visite venant de stripe.com oupaypal.com. La source publicitaire d’origine est perdue.

Sans exclusion de référents, la vente est attribuée au prestataire de paiement. Vos annonces n’affichent aucune vente. Votre rapport dit que PayPal a « amené » le client. La correction prend deux minutes dans GA4 (liste des référents indésirables), mais seulement si quelqu’un pense à la vérifier.

La solution d’ingénierie : une architecture JS natif propre

Plugins et usine à gaz vs. code natif

La plupart des sites trackent avec un empilement de plugins et de déclencheurs GTM qui lisent la page : « quand ce bouton avec cette classe CSS est cliqué, envoie un événement ». Ça marche jusqu’au jour où un designer renomme une classe. Le tracking casse et personne ne s’en aperçoit avant des semaines. Les plugins chargent aussi des scripts en plus, ce qui ralentit la page.

Je construis le tracking comme le reste de votre application : en JavaScript natif, avec un code court et lisible. Il est rapide, facile à maintenir et n’ajoute aucun poids au rendu de vos pages.

Découpler le tracking du DOM avec CustomEvent

Le code de votre application ne doit pas savoir que GA4 existe. Il doit seulement dire ce qui s’est passé. Le navigateur propose un outil natif pour ça : l’API CustomEvent. Quand un lead est confirmé, l’application l’annonce :

const addLeadEvent = new CustomEvent('app:lead_success', {
  detail: {
    formId: 'contact_pme',
    leadQuality: 'qualified',
    revenue: 500
  },
  bubbles: true
});
document.dispatchEvent(addLeadEvent);

Le nom de l’événement vous appartient (app:lead_success). Les données se trouvent dans detail. Commebubbles vaut true, tout écouteur situé plus haut peut l’attraper. Aucun sélecteur CSS n’est en jeu. Vous pouvez refondre le formulaire demain, le tracking continue de fonctionner.

Un seul écouteur global alimente le dataLayer

Un seul écouteur attrape l’événement et l’envoie dans window.dataLayeravec dataLayer.push() :

document.addEventListener('app:lead_success', (event) => {
  const { formId, leadQuality, revenue } = event.detail;

  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    event: 'generate_lead',
    form_id: formId,
    lead_quality: leadQuality,
    value: revenue
  });
});

Notez la ligne window.dataLayer = window.dataLayer || []. Elle crée le tableau seulement s’il n’existe pas encore. Le code utilise ensuitepush() et n’assigne jamais un nouveau tableau. C’est essentiel : si vous écrivez plus tard window.dataLayer = [...], vous effacez tous les événements déjà en file, y compris ceux de Google Tag Manager lui-même.

Résultat : un seul endroit à lire, un seul endroit à corriger, et une liste d’événements propre que je documente dans votre plan de taggage. L’audit vous livre ce plan, plus la liste de ce qui est cassé aujourd’hui et l’ordre dans lequel le corriger.