Bläddra i källkod

add nuxt-gtag and replace analytics and pixel

Olivier Massot 1 år sedan
förälder
incheckning
c935409a8d
7 ändrade filer med 147 tillägg och 154 borttagningar
  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',
     useError: 'readonly',
     Ref: 'readonly',
     Ref: 'readonly',
     watch: 'readonly',
     watch: 'readonly',
+    useGtag: 'readonly',
   },
   },
 }
 }

+ 124 - 62
components/Common/CookiesConsent.vue

@@ -1,6 +1,6 @@
 <template>
 <template>
   <div v-if="layoutStore.isCookieConsentDialogVisible">
   <div v-if="layoutStore.isCookieConsentDialogVisible">
-    <div class="cookie-consent-banner">
+    <div v-if="!showCustomizationOptions" class="cookie-consent-banner">
       <div class="continue-wrapper">
       <div class="continue-wrapper">
         <a class="continue" href="#" @click.prevent="continueWithoutAccepting">
         <a class="continue" href="#" @click.prevent="continueWithoutAccepting">
           Continuer sans accepter
           Continuer sans accepter
@@ -52,6 +52,7 @@
         <!-- <button class="decline-button" @click="declineCookies">Refuser</button> -->
         <!-- <button class="decline-button" @click="declineCookies">Refuser</button> -->
       </div>
       </div>
     </div>
     </div>
+
     <v-dialog v-model="showCustomizationOptions" persistent max-width="600px">
     <v-dialog v-model="showCustomizationOptions" persistent max-width="600px">
       <v-card>
       <v-card>
         <v-row class="headline">
         <v-row class="headline">
@@ -89,53 +90,90 @@
           <v-row align="center">
           <v-row align="center">
             <v-col cols="auto">
             <v-col cols="auto">
               <v-switch
               <v-switch
-                v-model="cookiesPreferences.allowGoogleAnalytics"
-                label="Google Analytics"
+                v-model="cookiesPreferences.analyticsConsent"
+                label="Mesure d'audience"
                 hide-details
                 hide-details
                 color="green"
                 color="green"
                 inset
                 inset
               />
               />
             </v-col>
             </v-col>
             <v-col>{{
             <v-col>{{
-              cookiesPreferences.allowGoogleAnalytics
-                ? 'Autorisé'
-                : 'Non-autorisé'
+              cookiesPreferences.analyticsConsent ? 'Autorisé' : 'Non-autorisé'
             }}</v-col>
             }}</v-col>
           </v-row>
           </v-row>
           <p>
           <p>
             Ces cookies nous permettent d'établir des statistiques, des volumes
             Ces cookies nous permettent d'établir des statistiques, des volumes
             de fréquentation et d'utilisation des divers éléments de notre site,
             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>
           </p>
+
           <h4 class="mt-6">Des cookies tiers à visée publicitaire</h4>
           <h4 class="mt-6">Des cookies tiers à visée publicitaire</h4>
 
 
           <v-row align="center">
           <v-row align="center">
             <v-col cols="auto">
             <v-col cols="auto">
               <v-switch
               <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
                 hide-details
                 color="green"
                 color="green"
                 inset
                 inset
               />
               />
             </v-col>
             </v-col>
             <v-col>{{
             <v-col>{{
-              cookiesPreferences.allowMetaPixel ? 'Autorisé' : 'Non-autorisé'
+              cookiesPreferences.advertisingConsent
+                ? 'Autorisé'
+                : 'Non-autorisé'
             }}</v-col>
             }}</v-col>
           </v-row>
           </v-row>
           <p>
           <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>
           </p>
         </v-card-text>
         </v-card-text>
 
 
@@ -172,7 +210,6 @@
 <script setup lang="ts">
 <script setup lang="ts">
 import { onMounted, type Ref, ref } from 'vue'
 import { onMounted, type Ref, ref } from 'vue'
 import { useCookies } from 'vue3-cookies'
 import { useCookies } from 'vue3-cookies'
-import CookieManager from '~/services/CookieManager'
 import { COOKIE_CONSENT_CHOICE } from '~/types/enum/enums'
 import { COOKIE_CONSENT_CHOICE } from '~/types/enum/enums'
 import type { CookiesPreferences } from '~/types/interface'
 import type { CookiesPreferences } from '~/types/interface'
 
 
@@ -182,12 +219,16 @@ const { cookies } = useCookies()
 const showCustomizationOptions = ref(false)
 const showCustomizationOptions = ref(false)
 const showNotification = ref(false)
 const showNotification = ref(false)
 
 
+const { gtag } = useGtag()
+
 /**
 /**
  * Cookies options
  * Cookies options
  */
  */
 const cookiesPreferences: Ref<CookiesPreferences> = ref({
 const cookiesPreferences: Ref<CookiesPreferences> = ref({
-  allowGoogleAnalytics: true,
-  allowMetaPixel: true,
+  analyticsConsent: true,
+  advertisingConsent: true,
+  adUserDataConsent: true,
+  adPersonalizationConsent: true,
 })
 })
 
 
 const showPopup = () => {
 const showPopup = () => {
@@ -204,58 +245,72 @@ const notify = () => {
   showNotification.value = true
   showNotification.value = true
 
 
   // Hide the notification after 1 minute
   // Hide the notification after 1 minute
-  // setTimeout(() => {
-  //   showNotification.value = false
-  // }, 60000)
+  setTimeout(() => {
+    showNotification.value = false
+  }, 60000)
 }
 }
 
 
 const setupCookies = (
 const setupCookies = (
   choice: COOKIE_CONSENT_CHOICE,
   choice: COOKIE_CONSENT_CHOICE,
-  allowGoogleAnalytics: boolean,
-  allowMetaPixel: boolean,
+  analyticsConsent: boolean,
+  advertisingConsent: boolean,
+  adUserDataConsent: boolean,
+  adPersonalizationConsent: boolean,
   duration: number = 365
   duration: number = 365
 ) => {
 ) => {
   cookies.set('cookie_consent', choice, duration + 'd')
   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
   // Store consent date and status
   localStorage.setItem(
   localStorage.setItem(
     'cookie_consent',
     'cookie_consent',
     JSON.stringify({
     JSON.stringify({
       date: new Date(),
       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
  * Accept and setup all the cookies and close the popup
  */
  */
 const acceptAllCookies = () => {
 const acceptAllCookies = () => {
-  setupCookies(COOKIE_CONSENT_CHOICE.ACCEPTED, true, true)
+  setupCookies(COOKIE_CONSENT_CHOICE.ACCEPTED, true, true, true, true)
   closePopup()
   closePopup()
 }
 }
 
 
@@ -263,7 +318,7 @@ const acceptAllCookies = () => {
  * Refuse all the cookies, set up the cookie_consent cookie and close the popup
  * Refuse all the cookies, set up the cookie_consent cookie and close the popup
  */
  */
 const declineCookies = () => {
 const declineCookies = () => {
-  setupCookies(COOKIE_CONSENT_CHOICE.DECLINED, false, false, 7)
+  setupCookies(COOKIE_CONSENT_CHOICE.DECLINED, false, false, false, false, 7)
   notify()
   notify()
   closePopup()
   closePopup()
 }
 }
@@ -274,8 +329,10 @@ const declineCookies = () => {
 const saveCookiesPreferences = () => {
 const saveCookiesPreferences = () => {
   setupCookies(
   setupCookies(
     COOKIE_CONSENT_CHOICE.CUSTOMIZED,
     COOKIE_CONSENT_CHOICE.CUSTOMIZED,
-    cookiesPreferences.value.allowGoogleAnalytics,
-    cookiesPreferences.value.allowMetaPixel
+    cookiesPreferences.value.analyticsConsent,
+    cookiesPreferences.value.advertisingConsent,
+    cookiesPreferences.value.adUserDataConsent,
+    cookiesPreferences.value.adPersonalizationConsent
   )
   )
   closePopup()
   closePopup()
 }
 }
@@ -288,9 +345,14 @@ const continueWithoutAccepting = () => {
 }
 }
 
 
 const loadActivePreferences = () => {
 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,
 .custom-switch,
 .v-input--selection-controls__input,
 .v-input--selection-controls__input,
 input:checked,
 input:checked,
-+ .v-input--selection-controls__ripple,
+.v-input--selection-controls__ripple,
 .v-ripple__container {
 .v-ripple__container {
   background-color: var(--v-primary-darken4);
   background-color: var(--v-primary-darken4);
 }
 }
@@ -430,7 +492,7 @@ input:checked,
 .custom-switch,
 .custom-switch,
 .v-input--selection-controls__input,
 .v-input--selection-controls__input,
 input:checked,
 input:checked,
-+ .v-input--selection-controls__ripple,
+.v-input--selection-controls__ripple,
 .v-ripple__container,
 .v-ripple__container,
 .v-ripple__animation {
 .v-ripple__animation {
   background-color: var(--v-primary-darken4);
   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',
           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: {
   typescript: {
@@ -140,6 +107,7 @@ export default defineNuxtConfig({
     'nuxt3-leaflet',
     'nuxt3-leaflet',
     '@nuxtjs/google-fonts',
     '@nuxtjs/google-fonts',
     '@nuxtjs/sitemap',
     '@nuxtjs/sitemap',
+    'nuxt-gtag',
   ],
   ],
   router: {
   router: {
     options: {
     options: {
@@ -203,4 +171,7 @@ export default defineNuxtConfig({
     },
     },
     display: 'block',
     display: 'block',
   },
   },
+  gtag: {
+    id: 'G-L8PZ9TEFNX',
+  },
 })
 })

+ 1 - 0
package.json

@@ -41,6 +41,7 @@
     "leaflet": "^1.9.3",
     "leaflet": "^1.9.3",
     "libphonenumber-js": "^1.10.55",
     "libphonenumber-js": "^1.10.55",
     "nuxt": "^3.11.2",
     "nuxt": "^3.11.2",
+    "nuxt-gtag": "^2.0.6",
     "nuxt-lodash": "^2.5.3",
     "nuxt-lodash": "^2.5.3",
     "nuxt3-leaflet": "^1.0.12",
     "nuxt3-leaflet": "^1.0.12",
     "ofetch": "^1.3.3",
     "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 {
 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
   languageName: node
   linkType: hard
   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":
 "nuxt-lodash@npm:^2.5.3":
   version: 2.5.3
   version: 2.5.3
   resolution: "nuxt-lodash@npm:2.5.3"
   resolution: "nuxt-lodash@npm:2.5.3"
@@ -11415,6 +11427,7 @@ __metadata:
     leaflet: "npm:^1.9.3"
     leaflet: "npm:^1.9.3"
     libphonenumber-js: "npm:^1.10.55"
     libphonenumber-js: "npm:^1.10.55"
     nuxt: "npm:^3.11.2"
     nuxt: "npm:^3.11.2"
+    nuxt-gtag: "npm:^2.0.6"
     nuxt-lodash: "npm:^2.5.3"
     nuxt-lodash: "npm:^2.5.3"
     nuxt3-leaflet: "npm:^1.0.12"
     nuxt3-leaflet: "npm:^1.0.12"
     ofetch: "npm:^1.3.3"
     ofetch: "npm:^1.3.3"