Parcourir la source

add nuxt-gtag and replace analytics and pixel

Olivier Massot il y a 1 an
Parent
commit
c935409a8d
7 fichiers modifiés avec 147 ajouts et 154 suppressions
  1. 1 0
      .eslintrc.cjs
  2. 124 62
      components/Common/CookiesConsent.vue
  3. 4 33
      nuxt.config.ts
  4. 1 0
      package.json
  5. 0 57
      services/CookieManager.js
  6. 4 2
      types/interface.d.ts
  7. 13 0
      yarn.lock

+ 1 - 0
.eslintrc.cjs

@@ -54,5 +54,6 @@ module.exports = {
     useError: 'readonly',
     Ref: 'readonly',
     watch: 'readonly',
+    useGtag: 'readonly',
   },
 }

+ 124 - 62
components/Common/CookiesConsent.vue

@@ -1,6 +1,6 @@
 <template>
   <div v-if="layoutStore.isCookieConsentDialogVisible">
-    <div class="cookie-consent-banner">
+    <div v-if="!showCustomizationOptions" class="cookie-consent-banner">
       <div class="continue-wrapper">
         <a class="continue" href="#" @click.prevent="continueWithoutAccepting">
           Continuer sans accepter
@@ -52,6 +52,7 @@
         <!-- <button class="decline-button" @click="declineCookies">Refuser</button> -->
       </div>
     </div>
+
     <v-dialog v-model="showCustomizationOptions" persistent max-width="600px">
       <v-card>
         <v-row class="headline">
@@ -89,53 +90,90 @@
           <v-row align="center">
             <v-col cols="auto">
               <v-switch
-                v-model="cookiesPreferences.allowGoogleAnalytics"
-                label="Google Analytics"
+                v-model="cookiesPreferences.analyticsConsent"
+                label="Mesure d'audience"
                 hide-details
                 color="green"
                 inset
               />
             </v-col>
             <v-col>{{
-              cookiesPreferences.allowGoogleAnalytics
-                ? 'Autorisé'
-                : 'Non-autorisé'
+              cookiesPreferences.analyticsConsent ? 'Autorisé' : 'Non-autorisé'
             }}</v-col>
           </v-row>
           <p>
             Ces cookies nous permettent d'établir des statistiques, des volumes
             de fréquentation et d'utilisation des divers éléments de notre site,
-            nous permettant d’optimiser son fonctionnement. Lien vers la
-            Politique de protection des données de Google Analytics :
-            <a href="https://policies.google.com/">
-              https://policies.google.com/</a
-            >
+            nous permettant d’optimiser son fonctionnement.
           </p>
+
           <h4 class="mt-6">Des cookies tiers à visée publicitaire</h4>
 
           <v-row align="center">
             <v-col cols="auto">
               <v-switch
-                v-model="cookiesPreferences.allowMetaPixel"
-                label="Meta Pixel"
+                v-model="cookiesPreferences.advertisingConsent"
+                label="Suivi publicitaire"
+                hide-details
+                color="green"
+                inset
+              />
+            </v-col>
+            <v-col>{{
+              cookiesPreferences.advertisingConsent
+                ? 'Autorisé'
+                : 'Non-autorisé'
+            }}</v-col>
+          </v-row>
+          <p>
+            Autoriser le stockage et l'accès aux cookies pour diffuser des
+            annonces publicitaires personnalisées. Cela permet de vous montrer
+            des publicités plus pertinentes.
+          </p>
+
+          <v-row align="center">
+            <v-col cols="auto">
+              <v-switch
+                v-model="cookiesPreferences.adUserDataConsent"
+                label="Données Utilisateur pour la Publicité"
                 hide-details
                 color="green"
                 inset
               />
             </v-col>
             <v-col>{{
-              cookiesPreferences.allowMetaPixel ? 'Autorisé' : 'Non-autorisé'
+              cookiesPreferences.advertisingConsent
+                ? 'Autorisé'
+                : 'Non-autorisé'
             }}</v-col>
           </v-row>
           <p>
-            Ces cookies sont installés par Facebook. Ce service nous permet
-            d'établir des statistiques de consultation des publicités. Lien vers
-            la Politique de protection des données de Facebook Pixel :
-            <a
-              href="https://www.facebook.com/privacy/policies/cookies/?entry_point=cookie_policy_redirect&entry=0"
-            >
-              https://www.facebook.com/privacy/policies/cookies/?entry_point=cookie_policy_redirect&entry=0
-            </a>
+            Autoriser la collecte et l'utilisation de vos données personnelles
+            (comme votre adresse e-mail ou numéro de téléphone) pour créer des
+            profils de publicité personnalisés et améliorer le ciblage des
+            annonces.
+          </p>
+
+          <v-row align="center">
+            <v-col cols="auto">
+              <v-switch
+                v-model="cookiesPreferences.adPersonalizationConsent"
+                label="Personnalisation des annonces"
+                hide-details
+                color="green"
+                inset
+              />
+            </v-col>
+            <v-col>{{
+              cookiesPreferences.advertisingConsent
+                ? 'Autorisé'
+                : 'Non-autorisé'
+            }}</v-col>
+          </v-row>
+          <p>
+            Autoriser la personnalisation des annonces en fonction de vos
+            préférences et de votre comportement de navigation pour vous offrir
+            des publicités plus pertinentes et ciblées.
           </p>
         </v-card-text>
 
@@ -172,7 +210,6 @@
 <script setup lang="ts">
 import { onMounted, type Ref, ref } from 'vue'
 import { useCookies } from 'vue3-cookies'
-import CookieManager from '~/services/CookieManager'
 import { COOKIE_CONSENT_CHOICE } from '~/types/enum/enums'
 import type { CookiesPreferences } from '~/types/interface'
 
@@ -182,12 +219,16 @@ const { cookies } = useCookies()
 const showCustomizationOptions = ref(false)
 const showNotification = ref(false)
 
+const { gtag } = useGtag()
+
 /**
  * Cookies options
  */
 const cookiesPreferences: Ref<CookiesPreferences> = ref({
-  allowGoogleAnalytics: true,
-  allowMetaPixel: true,
+  analyticsConsent: true,
+  advertisingConsent: true,
+  adUserDataConsent: true,
+  adPersonalizationConsent: true,
 })
 
 const showPopup = () => {
@@ -204,58 +245,72 @@ const notify = () => {
   showNotification.value = true
 
   // Hide the notification after 1 minute
-  // setTimeout(() => {
-  //   showNotification.value = false
-  // }, 60000)
+  setTimeout(() => {
+    showNotification.value = false
+  }, 60000)
 }
 
 const setupCookies = (
   choice: COOKIE_CONSENT_CHOICE,
-  allowGoogleAnalytics: boolean,
-  allowMetaPixel: boolean,
+  analyticsConsent: boolean,
+  advertisingConsent: boolean,
+  adUserDataConsent: boolean,
+  adPersonalizationConsent: boolean,
   duration: number = 365
 ) => {
   cookies.set('cookie_consent', choice, duration + 'd')
 
-  cookiesPreferences.value.allowGoogleAnalytics = allowGoogleAnalytics
-  cookies.set('ga_consent', allowGoogleAnalytics.toString(), duration + 'd')
-  if (allowGoogleAnalytics) {
-    CookieManager.makeGoogleAnalyticsCookies('UA-XXXXX-Y')
-  } else {
-    purgeGoogleCookies()
-  }
+  cookiesPreferences.value.analyticsConsent = analyticsConsent
+  cookies.set('analytics_consent', analyticsConsent.toString(), duration + 'd')
 
-  cookiesPreferences.value.allowMetaPixel = allowMetaPixel
-  cookies.set('mp_consent', allowMetaPixel.toString(), duration + 'd')
-  if (allowMetaPixel) {
-    CookieManager.makeMetaPixelCookies('1045498113172655')
-  } else {
-    purgeMetaCookies()
-  }
+  cookiesPreferences.value.advertisingConsent = advertisingConsent
+  cookies.set(
+    'advertising_consent',
+    advertisingConsent.toString(),
+    duration + 'd'
+  )
+
+  cookiesPreferences.value.adUserDataConsent = adUserDataConsent
+  cookies.set(
+    'ad_user_data_consent',
+    adUserDataConsent.toString(),
+    duration + 'd'
+  )
+
+  cookiesPreferences.value.adPersonalizationConsent = adPersonalizationConsent
+  cookies.set(
+    'ad_personalization_consent',
+    adPersonalizationConsent.toString(),
+    duration + 'd'
+  )
+
+  gtag('consent', 'update', {
+    analytics_storage: analyticsConsent ? 'granted' : 'denied',
+    ad_storage: analyticsConsent ? 'granted' : 'denied',
+    ad_user_data: adUserDataConsent ? 'granted' : 'denied',
+    ad_personalization: adPersonalizationConsent ? 'granted' : 'denied',
+  })
 
   // Store consent date and status
   localStorage.setItem(
     'cookie_consent',
     JSON.stringify({
       date: new Date(),
-      consent: { allowGoogleAnalytics, allowMetaPixel },
+      consent: {
+        analyticsConsent,
+        advertisingConsent,
+        adUserDataConsent,
+        adPersonalizationConsent,
+      },
     })
   )
 }
 
-const purgeGoogleCookies = () => {
-  cookies.remove('google') // TODO: complete
-}
-
-const purgeMetaCookies = () => {
-  cookies.remove('google') // TODO: complete
-}
-
 /**
  * Accept and setup all the cookies and close the popup
  */
 const acceptAllCookies = () => {
-  setupCookies(COOKIE_CONSENT_CHOICE.ACCEPTED, true, true)
+  setupCookies(COOKIE_CONSENT_CHOICE.ACCEPTED, true, true, true, true)
   closePopup()
 }
 
@@ -263,7 +318,7 @@ const acceptAllCookies = () => {
  * Refuse all the cookies, set up the cookie_consent cookie and close the popup
  */
 const declineCookies = () => {
-  setupCookies(COOKIE_CONSENT_CHOICE.DECLINED, false, false, 7)
+  setupCookies(COOKIE_CONSENT_CHOICE.DECLINED, false, false, false, false, 7)
   notify()
   closePopup()
 }
@@ -274,8 +329,10 @@ const declineCookies = () => {
 const saveCookiesPreferences = () => {
   setupCookies(
     COOKIE_CONSENT_CHOICE.CUSTOMIZED,
-    cookiesPreferences.value.allowGoogleAnalytics,
-    cookiesPreferences.value.allowMetaPixel
+    cookiesPreferences.value.analyticsConsent,
+    cookiesPreferences.value.advertisingConsent,
+    cookiesPreferences.value.adUserDataConsent,
+    cookiesPreferences.value.adPersonalizationConsent
   )
   closePopup()
 }
@@ -288,9 +345,14 @@ const continueWithoutAccepting = () => {
 }
 
 const loadActivePreferences = () => {
-  cookiesPreferences.value.allowGoogleAnalytics =
-    cookies.get('ga_consent') === 'true'
-  cookiesPreferences.value.allowMetaPixel = cookies.get('mp_consent') === 'true'
+  cookiesPreferences.value.analyticsConsent =
+    cookies.get('analytics_consent') !== 'false'
+  cookiesPreferences.value.advertisingConsent =
+    cookies.get('advertising_consent') !== 'false'
+  cookiesPreferences.value.adUserDataConsent =
+    cookies.get('ad_user_data_consent') !== 'false'
+  cookiesPreferences.value.adPersonalizationConsent =
+    cookies.get('ad_personalization_consent') !== 'false'
 }
 
 /**
@@ -422,7 +484,7 @@ onMounted(() => {
 .custom-switch,
 .v-input--selection-controls__input,
 input:checked,
-+ .v-input--selection-controls__ripple,
+.v-input--selection-controls__ripple,
 .v-ripple__container {
   background-color: var(--v-primary-darken4);
 }
@@ -430,7 +492,7 @@ input:checked,
 .custom-switch,
 .v-input--selection-controls__input,
 input:checked,
-+ .v-input--selection-controls__ripple,
+.v-input--selection-controls__ripple,
 .v-ripple__container,
 .v-ripple__animation {
   background-color: var(--v-primary-darken4);

+ 4 - 33
nuxt.config.ts

@@ -68,39 +68,6 @@ export default defineNuxtConfig({
           href: 'https://fonts.googleapis.com/css2?family=Barlow:wght@400;500;700&display=swap',
         },
       ],
-      script: [
-        // // Google Analytics
-        // {
-        //   src: 'https://www.googletagmanager.com/gtag/js?id=G-L8PZ9TEFNX',
-        //   async: true,
-        // },
-        // {
-        //   innerHTML: `
-        //     window.dataLayer = window.dataLayer || [];
-        //     function gtag(){dataLayer.push(arguments);}
-        //     gtag('js', new Date());
-        //     gtag('config', 'G-L8PZ9TEFNX');
-        //   `,
-        //   type: 'text/javascript',
-        // },
-        // // Meta Pixel
-        // {
-        //   src: 'https://connect.facebook.net/en_US/fbevents.js',
-        //   async: true,
-        // },
-        // {
-        //   innerHTML: `
-        //     !function(f,b,e,v,n,t,s){if(f.fbq)return;n=f.fbq=function(){n.callMethod?
-        //     n.callMethod.apply(n,arguments):n.queue.push(arguments)};if(!f._fbq)f._fbq=n;
-        //     n.push=n;n.loaded=!0;n.version='2.0';n.queue=[];t=b.createElement(e);t.async=!0;
-        //     t.src=v;s=b.getElementsByTagName(e)[0];s.parentNode.insertBefore(t,s)}(window,
-        //     document,'script','https://connect.facebook.net/en_US/fbevents.js');
-        //     fbq('init', '1045498113172655');
-        //     fbq('track', 'PageView');
-        //   `,
-        //   type: 'text/javascript',
-        // },
-      ],
     },
   },
   typescript: {
@@ -140,6 +107,7 @@ export default defineNuxtConfig({
     'nuxt3-leaflet',
     '@nuxtjs/google-fonts',
     '@nuxtjs/sitemap',
+    'nuxt-gtag',
   ],
   router: {
     options: {
@@ -203,4 +171,7 @@ export default defineNuxtConfig({
     },
     display: 'block',
   },
+  gtag: {
+    id: 'G-L8PZ9TEFNX',
+  },
 })

+ 1 - 0
package.json

@@ -41,6 +41,7 @@
     "leaflet": "^1.9.3",
     "libphonenumber-js": "^1.10.55",
     "nuxt": "^3.11.2",
+    "nuxt-gtag": "^2.0.6",
     "nuxt-lodash": "^2.5.3",
     "nuxt3-leaflet": "^1.0.12",
     "ofetch": "^1.3.3",

+ 0 - 57
services/CookieManager.js

@@ -1,57 +0,0 @@
-// Load Google Analytics script
-
-export default class CookieManager {
-  static makeGoogleAnalyticsCookies(id) {
-    ;(function (i, s, o, g, r, a, m) {
-      i.GoogleAnalyticsObject = r
-      ;(i[r] =
-        i[r] ||
-        function () {
-          ;(i[r].q = i[r].q || []).push(arguments)
-        }),
-        (i[r].l = 1 * new Date())
-      ;(a = s.createElement(o)), (m = s.getElementsByTagName(o)[0])
-      a.async = 1
-      a.src = g
-      m.parentNode.insertBefore(a, m)
-    })(
-      window,
-      document,
-      'script',
-      'https://www.googletagmanager.com/gtag/js?id=G-L8PZ9TEFNX',
-      'ga'
-    )
-
-    ga('create', id, 'auto')
-    ga('send', 'pageview')
-  }
-
-  static makeMetaPixelCookies(id) {
-    // Load Meta Pixel script
-    !(function (f, b, e, v, n, t, s) {
-      if (f.fbq) return
-      n = f.fbq = function () {
-        n.callMethod
-          ? n.callMethod.apply(n, arguments)
-          : n.queue.push(arguments)
-      }
-      if (!f._fbq) f._fbq = n
-      n.push = n
-      n.loaded = !0
-      n.version = '2.0'
-      n.queue = []
-      t = b.createElement(e)
-      t.async = !0
-      t.src = v
-      s = b.getElementsByTagName(e)[0]
-      s.parentNode.insertBefore(t, s)
-    })(
-      window,
-      document,
-      'script',
-      'https://connect.facebook.net/en_US/fbevents.js'
-    )
-    fbq('init', id)
-    fbq('track', 'PageView')
-  }
-}

+ 4 - 2
types/interface.d.ts

@@ -166,6 +166,8 @@ interface ContactFormData {
 }
 
 interface CookiesPreferences {
-  allowGoogleAnalytics: boolean,
-  allowMetaPixel: boolean
+  analyticsConsent: boolean,
+  advertisingConsent: boolean,
+  adUserDataConsent: boolean,
+  adPersonalizationConsent: boolean,
 }

+ 13 - 0
yarn.lock

@@ -9443,6 +9443,18 @@ __metadata:
   languageName: node
   linkType: hard
 
+"nuxt-gtag@npm:^2.0.6":
+  version: 2.0.6
+  resolution: "nuxt-gtag@npm:2.0.6"
+  dependencies:
+    "@nuxt/kit": "npm:^3.11.2"
+    defu: "npm:^6.1.4"
+    pathe: "npm:^1.1.2"
+    ufo: "npm:^1.5.3"
+  checksum: 10c0/584aa2399b4be9f8ce95b8f456eef8d2ca405caf0e10abc53a29826e39371cdc2f6bff24534179df81a6f437babc4994c4abbc3ffbaa6412908f33fb52355701
+  languageName: node
+  linkType: hard
+
 "nuxt-lodash@npm:^2.5.3":
   version: 2.5.3
   resolution: "nuxt-lodash@npm:2.5.3"
@@ -11415,6 +11427,7 @@ __metadata:
     leaflet: "npm:^1.9.3"
     libphonenumber-js: "npm:^1.10.55"
     nuxt: "npm:^3.11.2"
+    nuxt-gtag: "npm:^2.0.6"
     nuxt-lodash: "npm:^2.5.3"
     nuxt3-leaflet: "npm:^1.0.12"
     ofetch: "npm:^1.3.3"