Skip to content

Commit 7c3c96e

Browse files
cevhericlaude
andcommitted
fix: re-run cookie-consent inline script on View Transitions via data-astro-rerun
The astro:page-load listener approach (27fbb49) did not fire for the is:inline consent script after a client-side navigation. Switch to data-astro-rerun so the inline script itself re-executes on every transition: it rebinds the accept/decline buttons on the freshly-swapped DOM, records a GA/Meta page_view per SPA navigation, and keeps already-loaded state on window (which persists across swaps). All analytics globals are window-qualified. Runtime-verified on the production build with caching disabled. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 27fbb49 commit 7c3c96e

1 file changed

Lines changed: 43 additions & 36 deletions

File tree

src/components/CookieConsent.astro

Lines changed: 43 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -45,26 +45,29 @@
4545
/>
4646
</noscript>
4747

48-
<script is:inline>
48+
<!--
49+
data-astro-rerun: with <ClientRouter/>, this inline script re-executes on every
50+
View-Transition navigation, so the consent buttons get re-bound on the freshly
51+
swapped DOM and each SPA page records its own analytics page_view. Cross-navigation
52+
state (analytics already loaded?) is kept on `window`, which persists across swaps.
53+
-->
54+
<script is:inline data-astro-rerun>
4955
(function () {
50-
if (window.__libredbConsentWired) return;
51-
window.__libredbConsentWired = true;
52-
5356
var GA_ID = 'G-Q59L35YFPW';
5457
var META_PIXEL_ID = '25949277121347381';
5558
var STORAGE_KEY = 'libredb-cookie-consent';
56-
var analyticsLoaded = false;
5759

5860
function loadGA() {
59-
if (document.querySelector('script[src*="googletagmanager.com/gtag"]')) return;
61+
if (window.__libredbGA) return;
62+
window.__libredbGA = true;
6063
var s = document.createElement('script');
6164
s.async = true;
6265
s.src = 'https://www.googletagmanager.com/gtag/js?id=' + GA_ID;
6366
document.head.appendChild(s);
6467
window.dataLayer = window.dataLayer || [];
65-
window.gtag = window.gtag || function () { dataLayer.push(arguments); };
66-
gtag('js', new Date());
67-
gtag('config', GA_ID);
68+
window.gtag = window.gtag || function () { window.dataLayer.push(arguments); };
69+
window.gtag('js', new Date());
70+
window.gtag('config', GA_ID);
6871
}
6972

7073
function loadMetaPixel() {
@@ -77,20 +80,19 @@
7780
t.src=v;s=b.getElementsByTagName(e)[0];
7881
s.parentNode.insertBefore(t,s)}(window,document,'script',
7982
'https://connect.facebook.net/en_US/fbevents.js');
80-
fbq('init', META_PIXEL_ID);
83+
window.fbq('init', META_PIXEL_ID);
8184
}
8285

8386
function trackPageView() {
84-
if (window.gtag) gtag('event', 'page_view', { page_path: location.pathname, page_location: location.href, page_title: document.title });
85-
if (window.fbq) fbq('track', 'PageView');
87+
if (window.gtag) window.gtag('event', 'page_view', { page_path: location.pathname, page_location: location.href, page_title: document.title });
88+
if (window.fbq) window.fbq('track', 'PageView');
8689
}
8790

8891
function enableAnalytics() {
8992
loadGA();
9093
loadMetaPixel();
91-
analyticsLoaded = true;
9294
// GA `config` records this page; fire the single Meta PageView for it too
93-
if (window.fbq) fbq('track', 'PageView');
95+
if (window.fbq) window.fbq('track', 'PageView');
9496
}
9597

9698
function hideBanner() {
@@ -109,32 +111,37 @@
109111
}
110112
}
111113

112-
function wire() {
113-
var consent = localStorage.getItem(STORAGE_KEY);
114-
115-
if (consent === 'accepted') {
116-
if (!analyticsLoaded) enableAnalytics();
117-
else trackPageView();
118-
return;
119-
}
120-
if (consent === 'declined') return;
114+
var consent = localStorage.getItem(STORAGE_KEY);
121115

122-
// Not yet decided: show banner after 1s and (re)bind buttons on the freshly-rendered DOM
123-
setTimeout(showBanner, 1000);
116+
if (consent === 'declined') return;
124117

125-
var accept = document.getElementById('cookie-accept');
126-
var decline = document.getElementById('cookie-decline');
127-
if (accept) accept.addEventListener('click', function () {
128-
localStorage.setItem(STORAGE_KEY, 'accepted');
129-
hideBanner();
118+
if (consent === 'accepted') {
119+
// First time analytics are enabled this session, load them (GA `config` +
120+
// Meta PageView count this page). On later SPA navigations just track the view.
121+
if (window.__libredbAnalytics) {
122+
trackPageView();
123+
} else {
124+
window.__libredbAnalytics = true;
130125
enableAnalytics();
131-
});
132-
if (decline) decline.addEventListener('click', function () {
133-
localStorage.setItem(STORAGE_KEY, 'declined');
134-
hideBanner();
135-
});
126+
}
127+
return;
136128
}
137129

138-
document.addEventListener('astro:page-load', wire);
130+
// Not yet decided: show the banner after 1s and bind the buttons on this
131+
// (freshly swapped) DOM. A fresh node each navigation means no duplicate listeners.
132+
setTimeout(showBanner, 1000);
133+
134+
var accept = document.getElementById('cookie-accept');
135+
var decline = document.getElementById('cookie-decline');
136+
if (accept) accept.addEventListener('click', function () {
137+
localStorage.setItem(STORAGE_KEY, 'accepted');
138+
hideBanner();
139+
window.__libredbAnalytics = true;
140+
enableAnalytics();
141+
});
142+
if (decline) decline.addEventListener('click', function () {
143+
localStorage.setItem(STORAGE_KEY, 'declined');
144+
hideBanner();
145+
});
139146
})();
140147
</script>

0 commit comments

Comments
 (0)