From 5d30ec09b17d9f4420eca7bd7b490cf53e9dc11d Mon Sep 17 00:00:00 2001 From: Mohammed Elhaouari Date: Sat, 14 Feb 2026 18:07:44 +0100 Subject: [PATCH 1/3] Add consent for GPDR compliance --- packages/astro-gtm/LICENSE | 21 ++++ packages/astro-gtm/README.md | 118 +++++++++++++++++- packages/astro-gtm/src/GoogleTagManager.astro | 33 ++++- packages/astro-gtm/src/index.ts | 5 +- 4 files changed, 174 insertions(+), 3 deletions(-) create mode 100644 packages/astro-gtm/LICENSE diff --git a/packages/astro-gtm/LICENSE b/packages/astro-gtm/LICENSE new file mode 100644 index 00000000..10e5ba4e --- /dev/null +++ b/packages/astro-gtm/LICENSE @@ -0,0 +1,21 @@ +MIT License + +Copyright (c) 2025 Codiume + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/packages/astro-gtm/README.md b/packages/astro-gtm/README.md index 0bf12111..d9a55f62 100644 --- a/packages/astro-gtm/README.md +++ b/packages/astro-gtm/README.md @@ -11,7 +11,7 @@ This [Astro](https://astro.build/) plugin makes it easy to integrate [Google Tag ## 📋 Requirements -- Astro 4.0 or higher +- Astro 5.0 or higher - A Google Tag Manager account and container ID ## 📦 Installation @@ -55,6 +55,56 @@ import { GoogleTagManager } from 'astro-gtm'; ``` +## 🔐 Using Environment Variables + +It's recommended to store your GTM ID in environment variables rather than hardcoding it: + +### Step 1: Create `.env` file + +```bash +# .env file in your project root +PUBLIC_GTM_ID=GTM-XXXXXXX +``` + +**Important:** Use the `PUBLIC_` prefix for environment variables that need to be available in client-side code. + +### Step 2: Use in your component + +```astro +--- +import { GoogleTagManager } from 'astro-gtm'; +--- + + + + + + + + + + + +``` + +### Step 3: Add TypeScript types (optional) + +Create or update `src/env.d.ts`: + +```typescript +/// + +interface ImportMetaEnv { + readonly PUBLIC_GTM_ID: string; +} + +interface ImportMeta { + readonly env: ImportMetaEnv; +} +``` + +This provides autocompletion and type safety for your environment variables. + ## 📖 API Reference ### `` @@ -68,9 +118,75 @@ import { GoogleTagManager } from 'astro-gtm'; | `enableInDevMode` | `No` | `false` | `true` | Whether to enable Google Tag Manager in development mode. | | `auth` | `No` | `undefined` | `'WFcfQBD6HDw'` | Set preview auth for GTM workspace previews. | | `preview` | `No` | `undefined` | `'env-XXX'` | Set preview environment ID for GTM workspace previews. | +| `defaultConsent` | `No` | `undefined` | `{ ad_storage: 'denied' }` | Default consent state for Google Consent Mode v2. Required for GDPR compliance. | All props except `gtmId` are optional. The component will not render in development mode unless `enableInDevMode` is set to `true`. +## 🛡️ GDPR Compliance with Consent Mode + +Google Tag Manager supports Consent Mode v2, which is required for GDPR compliance in Europe. This package makes it easy to set default consent states before GTM initializes. + +### Setting Default Consent + +```astro +--- +import { GoogleTagManager } from 'astro-gtm'; +--- + + +``` + +### Updating Consent After User Accepts + +After the user accepts cookies through your consent banner, update the consent state: + +```html + + + +``` + +### Available Consent Types + +| Type | Description | +| :------------------------ | :---------------------------------------- | +| `ad_storage` | Enables storage for advertising purposes | +| `analytics_storage` | Enables storage for analytics purposes | +| `ad_user_data` | Consent for sending user data to Google | +| `ad_personalization` | Consent for personalized advertising | +| `functionality_storage` | Enables storage for website functionality | +| `personalization_storage` | Enables storage for personalization | +| `security_storage` | Enables storage for security purposes | + +**Note:** When `defaultConsent` is omitted, no consent mode is configured and GTM behaves according to your tag configuration. + +**Learn more:** [Google Consent Mode Documentation](https://developers.google.com/tag-platform/security/guides/consent) + ## 🔍 How It Works This package adds the necessary Google Tag Manager scripts to your page's `` tag. It: diff --git a/packages/astro-gtm/src/GoogleTagManager.astro b/packages/astro-gtm/src/GoogleTagManager.astro index 2ddd8516..5a3fad23 100644 --- a/packages/astro-gtm/src/GoogleTagManager.astro +++ b/packages/astro-gtm/src/GoogleTagManager.astro @@ -1,4 +1,14 @@ --- +export type ConsentDefaults = { + ad_storage?: 'granted' | 'denied'; + analytics_storage?: 'granted' | 'denied'; + ad_user_data?: 'granted' | 'denied'; + ad_personalization?: 'granted' | 'denied'; + functionality_storage?: 'granted' | 'denied'; + personalization_storage?: 'granted' | 'denied'; + security_storage?: 'granted' | 'denied'; +}; + export interface Props { /** * Google Tag Manager container ID (required) @@ -40,6 +50,13 @@ export interface Props { * @example 'env-1' */ preview?: string; + + /** + * Default consent state for Google Consent Mode v2 + * Set consent defaults before GTM initializes for GDPR compliance + * @see https://developers.google.com/tag-platform/security/guides/consent + */ + defaultConsent?: ConsentDefaults; } const { @@ -50,20 +67,34 @@ const { enableInDevMode = false, auth, preview, + defaultConsent, } = Astro.props; // Skip in development mode unless explicitly enabled const isDevelopment = import.meta.env.DEV; const shouldRender = !isDevelopment || enableInDevMode; + +// Validate GTM ID format +if (shouldRender && !/^GTM-[A-Z0-9]{5,}$/i.test(gtmId)) { + console.warn( + `[astro-gtm] Invalid GTM ID format: "${gtmId}". Expected format: GTM-XXXXXXX (e.g., GTM-ABC123)` + ); +} --- {shouldRender && ( -