# @pdntechnology/cookie-consent [![License: MIT](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE) [![npm version](https://img.shields.io/npm/v/@pdntechnology/cookie-consent.svg)](https://www.npmjs.com/package/@pdntechnology/cookie-consent) A lightweight, open-source **Consent Management Platform (CMP)** for React and Next.js that implements [Google Consent Mode v2](https://developers.google.com/tag-platform/security/guides/consent) the same way certified tools do. No heavy dependencies. No vendor lock-in. Works with Google Tag Manager, GA4, Google Ads, and Meta Pixel. --- ## Why this exists Google-certified CMPs (Cookiebot, OneTrust, CookieYes, …) follow the same technical flow: 1. Set **denied** defaults **before** any Google tag loads 2. Load GTM / gtag.js 3. Show a consent banner 4. On user choice → `gtag('consent', 'update', …)` + dataLayer event 5. When ads are denied → enable `ads_data_redaction` and `url_passthrough` This library implements that flow in ~15 KB of readable JavaScript. > **Note:** Certified CMPs additionally provide IAB TCF v2.2 signals and appear on Google's certified vendor list. This library covers the **Consent Mode v2 technical integration**. You are responsible for privacy policy text and legal compliance. --- ## Features - Google Consent Mode v2 (all 7 signals) - Granular categories: Necessary / Analytics / Marketing - `ads_data_redaction` + `url_passthrough` when marketing is denied - Regional default consent (EEA, etc.) - React banner + Next.js bootstrap component - Optional GTM and Meta Pixel loaders (consent-gated) - Framework-agnostic core API (vanilla JS supported) - TypeScript definitions included --- ## Installation ```bash npm install @pdntechnology/cookie-consent ``` ### Next.js setup Add to `next.config.mjs`: ```js const nextConfig = { transpilePackages: ["@pdntechnology/cookie-consent"], }; ``` --- ## Quick start ### 1. Configure (optional) ```js // lib/consent-config.js import { configureConsent } from "@pdntechnology/cookie-consent"; configureConsent({ storageKey: "my_site_consent", // localStorage key waitForUpdateMs: 500, // time GTM waits for consent update adsDataRedaction: true, // Google recommendation when ads denied urlPassthrough: true, // pass click IDs in URL when cookies denied debug: false, }); ``` Import this file in your root layout **before** `ConsentBootstrap`. ### 2. Bootstrap consent defaults (before GTM) ```jsx // app/layout.jsx import "@pdntechnology/cookie-consent/styles.css"; import "@/lib/consent-config"; import ConsentBootstrap from "@pdntechnology/cookie-consent/react/ConsentBootstrap"; export default function RootLayout({ children }) { return ( {children} ); } ``` ### 3. Banner + tags ```jsx // app/providers.jsx import { CookieConsent, GoogleTagManager, FacebookPixel, } from "@pdntechnology/cookie-consent/react"; export function Providers({ children }) { return ( <> {children} ); } ``` ### 4. Re-open preferences (footer link) ```jsx import { openPreferences } from "@pdntechnology/cookie-consent"; ``` --- ## How categories map to Google signals | Banner category | User choice | Google Consent Mode signals | |-----------------|-------------|----------------------------| | **Necessary** | Always on | `security_storage: granted` | | **Analytics** | Opt-in | `analytics_storage` | | **Marketing** | Opt-in | `ad_storage`, `ad_user_data`, `ad_personalization`, `functionality_storage`, `personalization_storage` | When marketing is **denied**, the library also sets: - `ads_data_redaction: true` - `url_passthrough: true` --- ## Project structure ``` src/ ├── index.js Public API ├── config.js configureConsent() ├── constants.js Events, signal names ├── preferences.js Parse / serialize user choices ├── storage.js localStorage read/write ├── consent-api.js acceptAll, rejectAll, getConsent, … ├── google/ │ ├── gtag.js dataLayer helpers │ ├── consent-signals.js Category → signal mapping │ ├── consent-lifecycle.js default + update calls │ └── bootstrap-script.js Inline script generator └── react/ ├── ConsentBootstrap.jsx ├── CookieConsent.jsx ├── GoogleTagManager.jsx └── FacebookPixel.jsx ``` --- ## API reference ### Configuration | Function | Description | |----------|-------------| | `configureConsent(config)` | Set storage key, wait time, region defaults | | `getConsentConfig()` | Read active configuration | ### User consent | Function | Description | |----------|-------------| | `getConsent()` | Read stored preferences | | `setConsent({ analytics, marketing })` | Save custom choice | | `acceptAll()` | Grant all categories | | `rejectAll()` | Deny optional categories | | `hasAnalyticsConsent()` | Check analytics opt-in | | `hasMarketingConsent()` | Check marketing opt-in | | `openPreferences()` | Re-open banner panel | | `syncConsentFromStorage()` | Re-apply stored consent after GTM loads | ### Google Consent Mode | Function | Description | |----------|-------------| | `getConsentBootstrapScript()` | Inline script for vanilla HTML | | `applyConsentDefaults()` | Set denied defaults programmatically | | `applyConsentUpdate(consent)` | Push user choice to gtag | | `buildGoogleConsentState(consent)` | Get signal object | ### Events | Constant | Fired when | |----------|------------| | `EVENT_CONSENT_UPDATED` | User saves a choice | | `EVENT_OPEN_PREFERENCES` | Preferences panel should open | | `GTM_CONSENT_EVENT` | Pushed to dataLayer (`cookie_consent_update`) | Legacy aliases (`getCookieConsent`, `acceptAllCookies`, …) remain available. --- ## Vanilla HTML (no React) ```html ``` Or generate the script programmatically: ```js import { getConsentBootstrapScript } from "@pdntechnology/cookie-consent"; console.log(getConsentBootstrapScript()); ``` --- ## GTM integration checklist 1. Enable **Consent Mode** in your GTM container settings 2. Configure GA4 / Google Ads tags to require appropriate consent signals 3. Optional: create a trigger on custom event `cookie_consent_update` 4. Test with [Tag Assistant](https://tagassistant.google.com/) --- ## Regional defaults (EEA example) ```js configureConsent({ regionDefaults: [ { regions: ["AT", "BE", "BG", "HR", "CY", "CZ", "DK", "EE", "FI", "FR", "DE", "GR", "HU", "IE", "IT", "LV", "LT", "LU", "MT", "NL", "PL", "PT", "RO", "SK", "SI", "ES", "SE", "IS", "LI", "NO"], ad_storage: "denied", analytics_storage: "denied", ad_user_data: "denied", ad_personalization: "denied", }, ], }); ``` --- ## Local development (link to another project) ```bash # In this repo cd cookie-consent npm link # In your Next.js app npm link @pdntechnology/cookie-consent ``` Or use a file dependency: ```json { "dependencies": { "@pdntechnology/cookie-consent": "file:../cookie-consent" } } ``` --- ## Publishing to npm ```bash npm login npm publish --access public ``` --- ## Contributing Contributions are welcome. Please open an issue before large changes. 1. Fork the repository 2. Create a feature branch 3. Submit a pull request --- ## License [MIT](LICENSE) © [PDN Technology](https://pdntechnology.com)