Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/constanza101/borrissol/llms.txt

Use this file to discover all available pages before exploring further.

Google Analytics 4 loads on every visit to borrissol.com via gtag.js, but it operates in a cookieless mode by default. Cookies are only set after the visitor explicitly clicks Accept on the cookie banner. This is achieved through Google Consent Mode v2 Advanced — the most privacy-preserving GA4 integration pattern available, and the one required for full GDPR compliance in EU markets like Spain and France. Consent Mode v2 separates the GA4 loading decision (always load) from the cookie decision (only set after consent). The flow on every page visit is:
1

Consent Mode initialized — denied by default

Before the GA4 snippet loads, Layout.astro initializes Consent Mode with all storage types set to denied. This is the “Advanced” pattern: the script loads, but Google is explicitly told it may not write cookies or read device storage.
window.dataLayer = window.dataLayer || [];
function gtag() { dataLayer.push(arguments); }

// Must run BEFORE the GA4 snippet
gtag('consent', 'default', {
  analytics_storage:  'denied',
  ad_storage:         'denied',
  ad_user_data:       'denied',
  ad_personalization: 'denied',
  wait_for_update:    500,
});
2

GA4 loads via gtag.js

The GA4 measurement script loads in the <head> of every page via Layout.astro. In denied state it fires a cookieless ping — Google uses this to model anonymous, aggregate traffic data without storing any PII.
3

Cookie banner is shown to new visitors

CookieBanner.astro checks localStorage for a previously saved consent decision. If no value is found, the banner is displayed with two actions: Accept and Decline.
4

Consent state updated on user action

When the visitor clicks Accept, the banner calls gtag('consent', 'update', { analytics_storage: 'granted' }) and saves 'accepted' to localStorage. GA4 then sets its measurement cookies and begins full tracking for that session and all future sessions.When the visitor clicks Decline, 'rejected' is saved to localStorage. The banner is dismissed and GA4 continues in cookieless mode for all future visits.
5

Consent restored on return visits

On every page load, Layout.astro reads localStorage inside the same inline script that sets the consent default. If the saved value is 'accepted', it calls gtag('consent', 'update', { analytics_storage: 'granted' }) immediately — before the GA4 snippet fires — so returning visitors never see the banner again and GA4 operates in full mode from the first pageview. CookieBanner.astro also reads localStorage independently to decide whether to show the banner at all.
The banner is a minimal two-button component rendered server-side by Astro and activated client-side:
  • Accept — updates consent to granted, saves 'accepted' to localStorage, hides the banner
  • Decline — saves 'rejected' to localStorage, keeps GA4 in cookieless mode, hides the banner
No cookies are read or written before the user makes a choice. The banner’s state is persisted entirely in localStorage, not in a cookie itself — keeping the pre-consent state clean.
The privacy policy text visible in PrivacySection.astro is translated for all four languages via ui.ts. The keys cookie.accept, cookie.decline, cookie.text, and privacy.* cover all banner and policy copy.

Layout.astro integration

Layout.astro is responsible for the correct script ordering in <head>:
  1. Consent Mode default initialization (inline <script> — must run synchronously)
  2. gtag.js loader (<script async src="https://www.googletagmanager.com/gtag/js?id=G-XXXXXXXX">)
  3. GA4 configuration call (gtag('config', 'G-XXXXXXXX'))
This order is critical. If the GA4 loader runs before the consent default is set, GA4 may attempt to write cookies before the denied state is registered.

What happens in denied state

In denied state (the default for new visitors and visitors who clicked Decline):
  • GA4 fires a cookieless ping on each pageview
  • Google applies modeled data — statistical inference that estimates traffic patterns from consented users and applies them to cookieless sessions
  • No PII is stored. No _ga or _gid cookies are written. No device fingerprinting occurs.
  • The site remains fully functional; the only difference is that individual sessions are not tracked
Google’s modeled data in Consent Mode v2 Advanced means aggregate traffic metrics (pageviews, sessions, bounce rate) remain useful in GA4 even when most visitors decline. The modeling accuracy improves over time as the proportion of consenting users provides a reference baseline.

GDPR compliance summary

RequirementImplementation
No cookies before consent✅ Consent Mode denied default blocks all GA4 cookies
Explicit consent required✅ Two-action banner (Accept / Decline), no pre-ticked boxes
Consent persistedlocalStorage — restored on return visits without re-asking
Right to withdraw✅ Visitor can clear browser localStorage/cookies at any time
Privacy policy✅ Inline PrivacySection.astro on every home page, translated in all 4 languages
Third-party analytics✅ GA4 only — no other tracking scripts

Adding tracking beyond GA4

Do not add cookies, pixel trackers, or third-party analytics scripts without updating CookieBanner.astro to include the new consent type. Every storage or tracking mechanism that requires GDPR consent must be gated behind the same gtag('consent', 'update', …) call that currently governs GA4. Adding a tracker outside this flow would break the site’s GDPR compliance.
If a second analytics service (e.g. a heatmap tool) is added in the future:
  1. Add the new consent category to the gtag('consent', 'default', …) defaults in Layout.astro
  2. Gate the tool’s initialization behind a gtag('consent', 'update', …) grant
  3. Update the privacy policy copy in ui.ts for all four languages to disclose the new tool

Build docs developers (and LLMs) love