Analytics.astro rendered <GoogleAnalytics> whenever config.yaml carried a
measurement id, so gtag ran and the _ga cookies were set on the first page
view, before the banner was answered and whatever the visitor went on to
choose. The analytics service in the consent config was never wired up to
anything -- its onAccept was a `// TODO: load ga4` -- so consent decided
nothing either way. The privacy policy says the opposite, that cookies are
used on the basis of consent given through the banner.
Analytics.astro now only defines window.loadGoogleAnalytics, and the ga4
service calls it from onAccept, so Google is first contacted after the visitor
accepts. Rejecting leaves the loader uncalled, and the library erases the _ga
cookies it already matches.
CookieConsent.astro skipped run() once its own localStorage flag was set,
which meant the library was not initialised on any later visit -- with the
loader moved behind consent that would have left analytics permanently dead
instead of permanently on, since re-applying a stored consent is what calls
onAccept. It now runs on every page load and lets the library decide whether
to show the banner.
Consent could also not be withdrawn: the preferences modal had no trigger
anywhere on the site, and the privacy policy offered browser settings instead,
which is not a withdrawal mechanism and is not as easy as giving consent was.
The footer now links to the modal and the policy points at it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01EZ49AbZJYfm8NTp5yDPMab