Google Analytics et Enhanced Ecommerce : implémenter intelligement avec Google Tag Manager

Aujourd’hui, j’ai le plaisir et l’honneur de m’attaquer à un gros morceau, sur lequel on m’a demandé pleeeeein de fois de documenter la façon dont je travaille : comment utiliser au maximum Google Tag Manager pour mettre en place une belle implémentation Enhanced Ecommerce, cette brique puissante mais tant redoutée de Google Analytics. Tenez, pas plus tard que la semaine dernière, ma boulangère me faisait encore remarquer qu’elle ne comprenait pas comment était constitué l’objet « Products » dans le push au data layer, et quel était le lien avec le product name dans les segments custom.

Cela fait un bon moment que je pratique l’Enhanced Ecommerce (que l’on va désormais appeler EEC, ça va, on est entre nous) dans Google Analytics, et, en particulier, que je suis en charge de mettre en place / maintenir les implémentations liées. Et on ne va pas se mentir, j’ai vu pas mal de cas de sites e-commerce où le sujet du tagging (de son évolution, de sa fiabilité…) était sensible. Genre, très sensible. Un jour, j’ai même vu un dèv recevoir un colis avec une tête de cheval décapité à l’intérieur et un mot écrit à l’encre rouge « JE TE RETROUVERAI, TOI QUI NE SAIT PAS IMPLÉMENTER UN ADD TO CART ».

Puisque me plaindre fait quasiment partie de ma fiche de poste, je vais dans un premier temps tenter d’expliquer pourquoi ces implémentations sont autant une source de douleur, puis je proposerai une solution éprouvée afin de rendre tout ça plus zen et cordial.

Prenez un bon thé / café, on va passer un bon moment ensemble.

Pourquoi les implémentations Enhanced Ecommerce sont souvent ratées

Commençons par le commencement : EEC est une feature relativement récente dans GA, et sort a différents égards du modèle antique sessions / pages vues / events…

Je ne vais pas égrener tout ce qu’il permet de mesurer, mais le catalogue est plutôt éloquent : on peut en effet tracker tout ce qui touche aux actions faites sur des produits, de l’impression à l’achat, en passant par le clic sur une promo et l’ajout panier. Même du côté du reporting à proprement parler, l’EEC met à dispo non seulement des rapports avec des metrics / dimensions propres aux produits…

… mais aussi et surtout ces délicieux rapports d’analyse des étapes du panier bien plus évolués que les tunnels de base tous claqués de jadis :

Cela nous amène donc à notre premier problème avec beaucoup d’implémentations : on démarre un setup EEC, et on essaie de mesurer toute la gamme de ce que fait EEC, de l’affichage du push de promo jusqu’à la transaction. Problème : le client ne le sait souvent pas, mais il n’est en général pas prêt à digérer autant de data pour prendre des décisions intelligentes. D’autant plus que même avec un niveau correct sur GA, faire de l’analyse sur EEC demande un bon paquet de connaissances supplémentaires. Sur lesquelles je ne reviendrai d’ailleurs pas ici, il y a déjà plein de très bons guides sur les internets.

Peu importe si c’est l’agence / consultant ou le client qui a été trop gourmand, il n’y a en général pas d’estimation qui est correctement faite du travail que ça va demander. Ce qui nous amène à notre second point.

Du sujet épineux du couplage GA/GTM

Bah oui, après tout, on a déjà GTM, non? GTM, ça permet d’avoir une relative flexibilité par rapport aux dèvs? L’implé EEC, elle va passer comme une lettre à la poste, n’est-ce pas?

Prenons un exemple hors e-commerce pour aborder le sujet avec un peu de recul : imaginons que mon site comporte différents formulaires, dont la validation se fait en AJAX (sans rechargement de page, donc). Techniquement, au moment de la soumission dudit formulaire, une réponse d’une API quelconque est reçue, et si cette réponse est positive, une div contenant quelque chose comme « OK merci nous reviendrons vers vous dans les plus brefs délais, Xoxo » est affichée.

Pour rentrer ça tranquillement dans GTM, puis donc GA, je vais donc simplement demander à mon dèv d’intégrer à son JS d’affichage du message de validation quelque chose comme ceci :

Ensuite, je n’ai plus qu’à mettre un trigger branché sur formValid et de router formTitle et formProduct comme je veux : soit dans un event action / event label, soit dans un nom de page si je veux faire une page vue virtuelle…

Voilà, là, nous sommes juste sur du GTM 101 : côté dèv front je fais déverser les informations de façon neutre (on pourrait aussi dire agnostique pour faire comme si on était à une conférence sur la transformation digitale), et je peux router ceci dans GTM. Si demain, je passe de GA à Adauby ou à AthéIhnternete, je pourrai adapter mon routing. Idem si je veux envoyer un tag de retargeting à la soumission du formulaire en question, pour lequel je pourrais utiliser ces paramètres sans aucun problème.

Il arrive malheureusement que l’on voie ce genre de choses poussées dans le data layer pour tracker ces formulaires :

Et côté GTM, cela va venir alimenter un « über tag d’event », qui ressemble plus ou moins à ceci :

Pourquoi ce genre de pratiques est une très mauvaise idée? Parce que cela créé un couplage fort entre GA et GTM. Concrètement, vous n’avez plus un Tag Management System, vous avec un Google Analytics Management System (GAMS, je vais le déposer). Et je ne veux pas entendre de « Ouais mais bon ça nous fait moins de boulot, et puis si jamais le dèv a mal bossé, on peut toujours rectifier au cas où ». Bah oui mais non. Parce que passer par GTM, ce n’est pas gratuit en termes de perf : il faut charger la librairie de GTM, le JSON de votre config, qu’il exécute toute sa logique, et enfin qu’il envoie GA.

Donc, de grâce, si vous faites ce genre de choses, mettez GA en dur, et focalisez vous sur les analyses. Voilà. J’ai fini.

Pourquoi cette digression beaucoup trop longue qui n’a a priori pas grand chose à voir avec EEC? Vous allez très vite comprendre. Mais pour cela, il va falloir faire un dernier petit détour, et se rendre dans la documentation de EEC avec GTM (un lien internet que vous avez déjà très certainement dans vos favoris, je n’en doute pas une seconde).

Exemple d’une page de transaction

Prenons l’exemple de ce que la doc nous conseille pour mesurer une transaction (purchase).

J’ai repris de façon bête et méchante les specs, en ajoutant simplement un event « purchase » sur cette page de démo au design élégant sur laquelle je ne saurais trop vous conseiller d’inspecter le code source (CTRL+U si vous êtes un être humain civilisé sur Linux ou Windows, ou quelque chose comme Pomme + CMD + Force Touch + Airplay + si vous avez un Mac, vous l’avez bien mérité).

Pour l’instant, contentons nous de regarder ce qui se passe du côté de la preview GTM :

Bien sûr, à ce stade rien ne part côté GA.

Si on respecte à la lettre la doc, voici ce qu’on doit faire dans GTM pour avoir une transaction :

Et le trigger qui va avec :

Une fois ceci en preview, on remonte bien ce qu’on attend :

Je pense que vous voyez parfaitement venir le truc : quand bien même vous avez sagement suivi la doc, nous sommes bien dans le cas typique d’un couplage fort entre GA et GTM. Votre TMS n’a absolument aucune intelligence, et ne fait que du passe-plat d’informations qui sont déjà préformatées rien que pour lui (le petit veinard).

Je vais tâcher de vous montrer pourquoi cette approche peut engendrer la fin de l’humanité (presque) : imaginons que mon gentil trafic manager me demande, à tout hasard, de lui envoyer un tag de remarketing au moment de la validation de la commande, qui ressemblerait à quelque chose comme ceci :

On va bien entendu passer par un tag de type HTML custom, pour lequel on devra un peu travailler pour obtenir les différentes variables demandées :

Pour commencer, la clé ‘orderPrice’ serait obtenue via une variable GTM comme ceci :

(oui, malgré tout, GTM nous facilite quand même un peu la vie pour ce qui est du parsing du data layer).

Quant à ce tableau de produit que l’on doit pousser dans la clé « productNames », il faudrait procéder en 2 temps. Tout d’abord, récupérer l’array de l’ensemble des produits de la même façon où GTM nous rend la vie plus simple :

Mais, et puisque nous n’avons besoin que des noms de produits, il va falloir faire un petit travail supplémentaire sur cette variable, et cette fois, par moyen d’échapper à un petit JS custom.

Et donc, une fois ceci fait, j’ai bien un array, ce dont je m’assure via le volet de preview…

…que je vais pouvoir donner à manger à mon tag de retargeting :

Pour ceux qui n’auraient pas une grande expérience de ce type de tags, et si ça vous semble un peu touffu, cette situation n’est absolument pas exceptionnelle. C’est typiquement le quotidien (horrible, du coup) des infortunés analystes qui gèrent des tags média sur des sites e-commerce.

Peut-être que Weborama voudra les produits sous forme d’Array, que Content Square ne les prendra que les IDs… ça vous paraît délirant? Là, je ne parle que de cas assez simples. Certains tags nécessitent de réimplémenter toute une logique produit, et peuvent parfois être une vraie tannée.

J’ai même entendu parler, dans les recoins des internets, de « double data layer » qui aurait été implémenté sur certains sites où l’analyste ne savait pas manipuler l’objet « GTMisé » comme ceci. Je pense que quelques dèvs ont dû rigoler grassement.

Puisqu’on parle de dèv, un autre problème sur ce genre de configuration est le fait qu’elle les fait travailler totalement à l’aveugle. Pour eux, ce « ‘ecommerce’: {‘purchase’: {‘actionField’: { » n’a aucune signification, et si par malheur ils embarquent directement l’array de produits au niveau du « purchase », ils ne sont en général pas formés à brancher GTM par eux-mêmes pour voir si la transaction part bien (ce qui est de toute façon complexe, GA étant d’une spectaculaire radinerie pour ce qui est des messages d’erreur de la validité des hits).

En fait, ce qui me questionne profondément dans cette histoire, c’est pourquoi Google préconise de faire ceci, bordel? Certes, le modèles de données de GA est déjà un peu particulier, et encore un peu plus tordu par EEC, mais je trouve ça relativement désolant d’avoir un outil aussi puissant que GTM à dispo, alors qu’eux-mêmes en recommandent d’en faire une sous-utilisation flagrante… Si quelqu’un a une explication, je serais très sincèrement preneur.

La solution avec un data layer à plat

Je vais arrêter de grogner, je pense que vous avez compris le sujet ; à la place, je vais vous donner la solution que je préconise pour toute implémentation EEC. Allons directement à la seconde page de démo : comme pour le « mauvais » exemple, nous allons imaginer qu’il s’agit d’une page de transaction.

Nous avons donc demandé à notre cher développeur de nous y déverser, de façon « neutre », toutes les infos liées à un produit, et à la transaction :

Histoire de ne pas se mélanger les pinceaux, les clés liées au produit sont préfixées par « product », celles liées à la transaction par « transaction ».

L’idée va donc être de faire un « mapper » qui va passer les infos d’un format « à plat » vers un format tel que GA l’attend, et de faire ceci dans GTM plutôt qu’en dur.

Première phase (un peu fastidieuse) : créer les variables dataLayer qui vont bien dans GTM :

Voilà, jusqu’ici, c’est comme coller des gomettes ; un petit checkup avec la preview pour s’assurer que tout répond bien :

C’est maintenant que démarre la partie (pas si) compliquée : nous allons créer notre mapper en JS :

Ici, il ne s’agit que d’un simple copier coller ce ce que préconise Google dans la partie « purchase », où l’on route tout bêtement les variables du data layer sur les clés de l’objet ‘products’, et où on finit, en plus, par pusher un event ‘mapperEEC’ dans le data layer.

En termes de trigger, nous allons simplement conditionner ce tag au chargement de la page de validation :

(Bien entendu, il faut adapter ce trigger au pattern de page de validation que vous avez sur votre « vrai » site).

Bon, tout ça, ça nous fait une belle jambe, mais à part pousser un event dans le data layer, nous n’avons encore rien envoyé à GA. Eh bien rien de plus simple : on commence par créer un trigger qui va aller chercher cet event que nous avons poussé en JS…

…Que l’on va attacher à un tag d’event GA :

Cet event n’est qu’un prétexte, bien sûr : l’important est de passer « Activer les fonctionnalités de e-commerce amélioré » sur « Vrai », et de cocher « Utiliser la couche de données », ce qui viendra populer nos rapports de transaction. On pourrait aussi bien pousser une page vue, ça ne changerait pas la face du monde (il s’agit simplement de « porter » les infos EEC).

Il n’y a plus qu’à s’assurer qu’une fois en preview, nous avons bien le tag attendu :

Alors, c’était si compliqué que ça?

Mainenant, reprenons l’exemple de notre tag média sus-mentionné. Pour rappel, le tag attendait ce genre de choses :

Pour venir le nourrir, rien de plus simple avec notre data layer aussi plat que les Monts d’Arrée :

Et imaginons que demain, un tag quelconque (disons un tag Google Ads, histoire de changer un peu) vous demande une nouvelle info que vous n’utilisez pas pour GA (par exemple, le type de livraison de la commande, express ou standard) : dans la logique « à couplage fort », vous devriez soit le mettre en place dans l’objet « GoogleAnalyticsisé », puis le détricotter comme en partie 1, ou bien le mettre à part, dans un data layer « hors GA » (bonjour le chantier).

Dans le cas où tout est déversé à plat, faire ajouter des infos sur le produit est en général une formalité pour votre développeur, qui est désormais votre meilleur ami, juste après Patrick de la compta (sacré Patrick).

Gestion du multiproduit

Alors oui, bien évidemment, je vous vois venir.

« Ton truc c’est bien joli là, mon petit pote ; mais ta solution elle marche pour une transaction à un seul produit. Comment est ce que moi je fais si j’ai des transactions multiproduits? »

J’aurais bien tendance à vous dire « il y a une page de contact sur mon site, c’est avec grand plaisir que je vous ferai un devis pour effectuer cette tâche surhumaine ». Mais je suis dans un grand élan de générosité (et accessoirement au chômage) en ce moment , donc je vous vais vous livrer ma recette super simple en fait qui nécessite un niveau de ninja en JS.

Pour commencer, voici la troisième et dernière page de démo qui va traiter ce cas. Fermez les yeux et concentrez vous : nous sommes dans le cas d’une transaction qui comporte non pas 1, mais 2 produits (pfiou)!

Et comme vous pouvez le voir dans le data layer, nous avons exactement les mêmes informations, si ce n’est que les infos sur les différents produits sont séparées par des pipes :

Nous allons donc améliorer notre script avec une technique Javascript qui nécessite plus de 15 ans de théorie en computer science, j’ai nommé une boucle for :

Ce script se décompose donc en 3 parties très simples :

  • La première consiste tout bêtement à passer nos produits « stringifiés » en tableaux JS (au passage : please, Google, sortez vous les doigts et laissez nous faire de la syntaxe ES6+ dans GTM, la répétitivité de ce code me donne envie de me flageller avec du fil barbelé, il y aurait moyen de faire tellement mieux avec de l’array destructuring). On créé également « eecProduct », un tableau vide, qui va devenir un tableau tel que GA l’attend.
  • On va donc ensuite simplement alimenter ce « eecProduct » via notre fameuse boucle for, qui va tourner autant de fois qu’il y a de produits sur la page.
  • Ensuite, on fait simplement notre ecommerce.purchase.actionfield… pas de changement de ce côté, nos informations de transaction sont déjà relatives à l’ensemble de la transaction, pas à un produit en particulier. On peut donc faire du passe plat comme dans le cas du monoproduit, pas de boucle nécessaire.

(oui, on pourrait tout à fait se la jouer puriste, et plutôt que de mettre tout ça dans une string, avoir un array pour tous les prix, un autre pour toutes les catégories, etc…, voire un gros objet de produits global, que l’on pourrait parser de la même façon).

Inutile de me répéter, côté GTM ça sera exactement la même chose que pour le monoproduit, avec un tag de page ou d’event GA qui va aller lire le data layer :

Oh et puis allez, on va quand même aller jeter un œil à la console :

Voilà, on retrouve nos petits, avec nos 2 produits qui remontent bien séparément.

J’ai volontairement fait un tag de transaction plutôt épuré, mais bien évidemment, ajouter un product variant, ou tout un tas de custom dimensions… devient un jeu d’enfant.

Gérer l’ensemble des actions EEC

Bien évidemment, un setup enhanced e-commerce ne se limite pas aux transactions : vous mesurez très probablement les ajouts panier, les étapes du panier (paiement, choix de l’adresse, de la livraison…), les impressions, les clics sur les promos…

Certaines de ces actions peuvent êtres liées au chargement des pages (Checkout steps, Product view…) : dans ce cas, vous pouvez tout à fait faire un mapper qui part au Page View, et fonctionne sur la même logique que celui que je vous ai montré. Vous pourrez ensuite avoir le trigger qui va bien pour que le mapper ne se déclenche que sur les pages qui génèrent l’action en particulier. Ou alors, libre à vous, s’il n’est pas simple d’identifier un product view sur un pattern d’URL simple, de demander à votre dèv d’ajouter un attribut au data layer du type « productAction », ce qui n’est en général pas plus compliqué.

Certaines autres actions (typiquement, la suppression d’un produit du panier) peuvent quant à elles se passer purement en JS : dans ce cas, le principe est le même, et vous pouvez tout à fait déverser les infos à plat, si ce n’est qu’il faudra bien sûr pousser un event du type « removeFromCart » :

On peut donc faire un mapper par type d’action EEC : un mapper pour les transactions, un pour les ajouts paniers, etc… ce qui fait totalement le job et est plutôt simple à maintenir.

Si vous êtes un puriste et que vous voulez absolument éviter de vous répéter, il est aussi possible de faire un gros mapper qui se déclenchera dans tous les cas (ajout panier, transaction…), c’est à dire à la fois des chargements de page et des actions en JS, et dans lequel vous ferez un gros switch…case sur le type d’event qui part dans le data layer. Je ne vais pas m’étendre là dessus, ça ne change pas le concept d’indépendance GA/GTM en profondeur, mais ça peut avoir son importance sur de grosses implémentations, et avec du code élégant et scalable.

EEC et CMS

Je suis obligé de parler des différents frameworks e-commerce si je veux que cet article atteigne sa complétude la plus totale. Et d’ailleurs, si j’avais été un peu plus honnête, j’aurais même pu aborder ce point en amont de toute ma diatribe sur le data layer à plat.

Il est en effet fort probable que, si vous travaillez sur un site e-commerce, ce dernier utilise un CMS comme Prestashop, Shopify, WooCommerce (de WordPress) ou encore Magento pour un plus gros site. Et il existe en général des plugins pour ces CMS, qui intègrent très bien EEC.

L’objet n’est pas de faire un listing complet, mais on peut en répertorier quelques uns :

Alors OUI, l’immense majorité de ces plugins imposent une logique de couplage fort : on ne peut pas en vouloir à leurs concepteurs, ils n’ont fait que lire la doc. Et cela vous permet parfois d’avoir une implé EEC super complète en 1 clic (que vous allez quand même facturer, il faut bien manger hein).

Donc, votre réflexe doit être de demander au dèv / à l’agence qui s’est occupé du site son avis : présentez les 2 possibilités, les avantages & inconvénients d’un data layer à plat ou d’un plugin. A savoir qu’un bon plugin est en général plus efficace qu’un mauvais dèv.

Si vous partez sur un data layer à plat (ou si vous avez besoin d’argument pour le vendre à votre client), il faut quand même savoir les attributs que l’on va passer à GA, du type ID de produit, catégorie, variante… font souvent partie du b.a.-ba des modèles de données qu’il y a derrière ces CMS, et ne sont pas d’une complexité affreuse à calculer server side et à pousser dans le data layer. En particulier dans le cas d’un site tout neuf ou d’une refonte, ajouter un data layer à plat relève souvent de la broutille pour un dèv qui doit de toute façon customiser un minimum.

Spoiler alert : n’allez pas crever les pneus de ma voiture si jamais vous utilisez un de ces plugins et qu’il s’avère qu’il produit des effets inattendus. Selon le degré de customisation / dette technique que vous avez sur votre CMS, il se peut que votre panier magique qui utilise une solution tierse, en flash et appelée en iframe dans un composant Angular.js, ne se comporte pas totalement comme Magento l’attendait #dézo.

Autre point important : si vous partez sur une solution à base de plugin, et sous réserve que vous ayez la bénédiction du dèv, il est souvent possible de tester ceci sur une préprod. Et si ça vous coûte quelques dizaines d’euros, eh bien au pire vous partirez en vacances à Châteauroux plutôt qu’à Ibiza l’été prochain (et encore une fois, mollo avec les pneus de ma voiture).

Conclusion

Et voilà une bonne chose de faite. Le setup EEC est un sujet qui me tenait à cœur et sur lequel je voulais écrire depuis un moment, car quand on regarde un peu le détail, il n’y a finalement pas grand chose qui relève de la virtuosité côté Javascript.

Et si beaucoup d’implémentations, sans aller jusqu’à dire qu’elles sont ratées, présentent un couplage trop fort entre GA et GTM, je tiens une nouvelle fois à dire que c’est avant tout la faute de Google (dézo) et de leur documentation qui devrait à mon humble avis être plus libérale.

Je suis donc super super curieux d’avoir vos retours d’expérience sur les implémentations EEC. Enfin, je suis toujours curieux d’avoir vos retours, mais là, encore plus que d’habitude. Vraiment. Je sais qu’il existe d’ardents défenseurs des 2 approches, et si, comme vous l’avez compris, j’ai choisi mon camp depuis un bon moment, je serai ravi d’avoir les arguments en faveur / défaveur des solutions, car il y en a forcément plein qui m’ont échappé.

Kiss, flex, et volupté.

Toujours mieux et encore plus loin

Laisser un commentaire

Votre adresse de messagerie ne sera pas publiée. Les champs obligatoires sont indiqués avec *