From 88497a38481057bd92faa3e75b0f5bd7270c2708 Mon Sep 17 00:00:00 2001 From: Remi <73385395+itsrubberduck@users.noreply.github.com> Date: Thu, 18 Sep 2025 13:36:27 +0200 Subject: [PATCH] Fix Hotjar loading after cookie consent --- nuxt.config.ts | 1 - plugins/hotjar.client.ts | 62 ++++++++++++++++++++++++---------------- 2 files changed, 38 insertions(+), 25 deletions(-) diff --git a/nuxt.config.ts b/nuxt.config.ts index 57d2e26..d8b29af 100644 --- a/nuxt.config.ts +++ b/nuxt.config.ts @@ -9,7 +9,6 @@ export default defineNuxtConfig({ 'nuxt-aos', '@pinia/nuxt', 'nuxt-mongoose', - 'nuxt-module-hotjar', '@nuxt/image', ], aos: {once: true, duration: 600, easing: 'ease-out'}, diff --git a/plugins/hotjar.client.ts b/plugins/hotjar.client.ts index 28ba0b5..124f994 100644 --- a/plugins/hotjar.client.ts +++ b/plugins/hotjar.client.ts @@ -1,3 +1,4 @@ +import type { Ref } from 'vue'; import { watch } from 'vue'; declare global { @@ -12,15 +13,11 @@ const HOTJAR_ID = 6522897; const HOTJAR_VERSION = 6; const HOTJAR_SCRIPT_ID = 'hotjar-tracking-script'; -const injectHotjar = () => { +const ensureHotjarStub = () => { if (typeof window === 'undefined') { return; } - if (window.hj && window._hjSettings?.hjid === HOTJAR_ID) { - return; - } - window.hj = window.hj || function (...args: unknown[]) { @@ -28,14 +25,16 @@ const injectHotjar = () => { }; window._hjSettings = { hjid: HOTJAR_ID, hjsv: HOTJAR_VERSION }; +}; +const appendHotjarScript = () => { if (document.getElementById(HOTJAR_SCRIPT_ID)) { - return; + return true; } const head = document.head || document.getElementsByTagName('head')[0]; if (!head) { - return; + return false; } const script = document.createElement('script'); @@ -43,6 +42,33 @@ const injectHotjar = () => { script.async = true; script.src = `https://static.hotjar.com/c/hotjar-${HOTJAR_ID}.js?sv=${HOTJAR_VERSION}`; head.appendChild(script); + return true; +}; + +const enableHotjar = (hasLoaded: Ref) => { + if (typeof window === 'undefined') { + return; + } + + window._hjOptOut = false; + + if (hasLoaded.value) { + return; + } + + ensureHotjarStub(); + + if (appendHotjarScript()) { + hasLoaded.value = true; + } +}; + +const disableHotjar = () => { + if (typeof window === 'undefined') { + return; + } + + window._hjOptOut = true; }; export default defineNuxtPlugin(() => { @@ -53,27 +79,15 @@ export default defineNuxtPlugin(() => { const { analyticsEnabled } = useCookieConsent(); const hasLoaded = useState('hotjar-loaded', () => false); - const loadIfNecessary = () => { - if (!hasLoaded.value) { - injectHotjar(); - hasLoaded.value = true; - window._hjOptOut = false; - } - }; - - if (analyticsEnabled.value) { - loadIfNecessary(); - } - watch( - analyticsEnabled, + () => analyticsEnabled.value, (allowed) => { if (allowed) { - loadIfNecessary(); - } else if (typeof window !== 'undefined') { - window._hjOptOut = true; + enableHotjar(hasLoaded); + } else { + disableHotjar(); } }, - { immediate: false } + { immediate: true } ); });