GTM, Nuxt 3 et RGPD : Le Guide pour une Implémentation Conforme
Depuis mars 2024, Google impose le Consent Mode v2 pour toute collecte de données dans l'Espace Économique Européen. Beaucoup d'intégrations de GTM dans Nuxt sont incorrectes et exposent à des fuites de données et des sanctions. Ce guide technique vous montre, étape par étape, comment construire une solution robuste qui respecte le RGPD sans sacrifier vos données analytiques.
Étape 1 : Verrouiller GTM par défaut. Pourquoi c'est
La seule approche viable pour une conformité RGPD est de considérer que tout suivi est interdit jusqu'à preuve du contraire. Cela signifie que GTM ne doit jamais se charger avant le consentement explicite de l'utilisateur. Tenter de charger GTM puis de bloquer les balises est une course perdue d'avance qui mène à des fuites de données.
Installation du module @nuxtjs/gtm
On commence par ajouter le module GTM à notre projet Nuxt 3. C'est le point de départ technique qui nous donnera les outils nécessaires.
# npm
npm install @nuxtjs/gtm --save
# yarn
yarn add @nuxtjs/gtm
Configuration cruciale dans nuxt.config.ts
Voici la pièce maîtresse de la conformité. Dans votre fichier nuxt.config.ts, nous déclarons le module mais nous le désactivons immédiatement. C'est cette ligne qui fait toute la différence.
export default defineNuxtConfig({
modules: [
'@nuxtjs/gtm',
],
gtm: {
id: 'GTM-XXXXXXX', // Remplacez par votre ID
enabled: false, // La ligne la plus importante de ce guide
debug: process.env.NODE_ENV === 'development', // Utile pour le débogage local
compatibility: false // Recommandé pour Nuxt 3
}
})
Avec enabled: false, aucun script GTM n'est injecté, aucun cookie n'est déposé. Votre site est "propre" par défaut. Nous avons maintenant le contrôle total pour décider quand et comment activer le suivi.
Étape 2 : Créer une source de vérité pour le consentement avec
La gestion du consentement ne peut pas être éparpillée. Nous allons centraliser toute la logique dans un composable useConsent. Il aura deux responsabilités : gérer l'état actuel du consentement pour l'UI et mémoriser le choix de l'utilisateur entre les sessions.
Combiner useState et useCookie
Nous avons besoin de deux outils de Nuxt 3 pour une gestion parfaite :
useState: Pour créer un état réactif (true,false, ounull) qui mettra à jour notre interface (comme le bandeau) instantanément. Il assure la synchronisation entre le serveur et le client, évitant les clignotements de l'UI.useCookie: Pour stocker le choix de l'utilisateur. Sans cela, il faudrait lui redemander son avis à chaque page. Le cookie est la mémoire de notre système de consentement.
Dans votre composable useConsent, vous allez lire le cookie au démarrage. S'il existe, vous initialisez l'état useState avec sa valeur. Quand l'utilisateur fait un choix, vous mettez à jour l'état et le cookie simultanément. Cette double action garantit une UI réactive et un choix persistant.
Étape 3 : Un bandeau de cookies réactif et découplé
Le bandeau est la seule partie visible par l'utilisateur. Il doit être simple, clair et directement connecté à notre logique centralisée. Nous créons un composant CookieBanner.vue qui ne contient aucune logique métier, il ne fait qu'appeler les fonctions de notre composable useConsent.
Structure du composant CookieBanner.vue
Le template est conditionné par l'état de notre composable. S'il n'y a pas de consentement enregistré, on l'affiche.
<template>
<div v-if="!consent.isConsentGiven" class="cookie-banner">
<p>Ce site utilise des cookies. Acceptez-vous leur utilisation pour l'analyse et la publicité ?</p>
<div class="cookie-banner-actions">
<button @click="accept">Tout accepter</button>
<button @click="reject">Tout refuser</button>
</div>
</div>
</template>
<script setup>
import { useConsent } from '@/composables/useConsent';
const { consent, accept, reject } = useConsent();
</script>
Le composant est "bête". Il ne sait pas comment stocker le consentement ou activer GTM. Il se contente d'appeler accept() ou reject(). Toute l'intelligence reste dans useConsent, ce qui rend le code facile à maintenir et à tester.
Étape 4 : Activation contrôlée et communication avec le
C'est le moment de vérité. L'utilisateur a cliqué sur "Accepter". Nous devons maintenant exécuter une séquence d'actions précise pour activer le suivi de manière conforme.
Activer GTM avec $gtm.enable()
Le module Nuxt GTM nous fournit la fonction $gtm.enable(). C'est elle qui va injecter le script gtm.js dans la page. Cette fonction doit être appelée uniquement depuis notre logique de consentement, après le clic sur "Accepter".
// Dans la fonction accept() de votre composable useConsent
function accept() {
const gtm = useGtm();
if (!gtm.enabled()) {
gtm.enable(); // Active GTM maintenant !
}
// ... la suite juste après
}
Pousser l'état du consentement vers le dataLayer
Juste après avoir activé GTM, il faut lui dire quelles permissions ont été accordées. C'est le rôle du Consent Mode v2. On pousse un événement consent avec le paramètre update dans le dataLayer.
La séquence complète dans votre fonction accept() est donc :
- Mettre à jour l'état local et le cookie.
- Appeler
$gtm.enable()si ce n'est pas déjà fait. - Pousser l'état du consentement vers le
dataLayer.
// Suite de la fonction accept()
window.dataLayer = window.dataLayer || [];
window.dataLayer.push({
'gtm.consent': {
'update': {
'ad_storage': 'granted',
'analytics_storage': 'granted',
'ad_user_data': 'granted',
'ad_personalization': 'granted'
}
}
});
Cette séquence garantit qu'il n'y a aucune "race condition". GTM est activé et immédiatement informé des permissions, assurant une collecte de données fiable et conforme dès le départ.
Étape 5 : Gérer la révocation du consentement
Le RGPD stipule que retirer son consentement doit être aussi simple que de le donner. Votre application doit donc proposer un moyen permanent de gérer ses préférences (un lien en pied de page, par exemple).
Mettre à jour le consentement
Quand un utilisateur décide de révoquer son consentement (par exemple, en passant de "tout accepter" à "tout refuser"), votre application doit :
- Mettre à jour le cookie pour mémoriser ce nouveau choix.
- Pousser un nouvel événement de mise à jour du consentement vers le
dataLayerpour informer GTM du changement en temps réel.
// Exemple de fonction de révocation
function revokeConsent() {
// ... mettre à jour le cookie
window.dataLayer.push({
'gtm.consent': {
'update': {
'analytics_storage': 'denied',
'ad_storage': 'denied'
// ... etc
}
}
});
}
Grâce au Consent Mode, GTM cessera immédiatement d'envoyer des données aux services Google concernés pour toutes les actions futures de l'utilisateur sur la page, sans avoir besoin de la recharger.
Foire Aux Questions : GTM sur Nuxt 3 : Conformité RGPD
- Comment vérifier si GTM est bien bloqué avant le consentement ?
-
Utilisez les outils de développement de votre navigateur (F12) :
- Onglet Réseau : Chargez votre site. Filtrez par "gtm.js". Aucune requête ne doit apparaître. Cliquez sur "Accepter" sur votre bandeau : la requête vers
googletagmanager.com/gtm.jsdoit alors apparaître. - Onglet Application : Avant consentement, vérifiez la section Cookies. Aucun cookie comme
_gaou_gidne doit être présent. Ils ne doivent être créés qu'après votre clic. - Tag Assistant : Utilisez l'extension Google Tag Assistant ou le mode Preview de GTM. Il doit vous montrer l'état de consentement (par défaut "denied") et confirmer qu'aucune balise ne se déclenche à l'initialisation.
- Onglet Réseau : Chargez votre site. Filtrez par "gtm.js". Aucune requête ne doit apparaître. Cliquez sur "Accepter" sur votre bandeau : la requête vers
- Le Google Consent Mode v2 est-il vraiment obligatoire ?
- Légalement, le RGPD n'impose pas GCM v2. Il impose le recueil du consentement. Cependant, en pratique, oui, il est obligatoire si vous utilisez Google Analytics ou Google Ads. Depuis mars 2024, sans GCM v2, Google ne collectera plus de données pour vos audiences de remarketing et vos conversions pour les utilisateurs de l'EEE. Ne pas l'implémenter revient à rendre vos outils Google quasiment inutiles.
- Cette méthode fonctionne-t-elle avec Nuxt 2 ?
- Oui, le principe est identique. Vous utiliserez le module
@nuxtjs/google-tag-managerpour Nuxt 2, en configurantenabled: false. La gestion d'état se fera probablement avec Vuex etcookie-universal-nuxtau lieu des composables, mais la logique d'activation (this.$gtm.init()) et de push dans ledataLayerreste la même. - Comment gérer un consentement granulaire (analytique oui, pub non) ?
- Votre état de consentement ne doit plus être un simple booléen, mais un objet. Par exemple :
{ analytics_storage: 'granted', ad_storage: 'denied' }. Votre bandeau doit proposer des cases à cocher pour chaque catégorie, qui mettront à jour cet objet. Ensuite, vous poussez dynamiquement cet objet dans ledataLayerlors de la mise à jour du consentement. GTM s'occupera d'activer les balises correspondantes.