Add GDPR compliant optional tracking solution

- Complete demo with privacy-first hero section and live status indicator
- Production-ready integration examples for React, Vue, WordPress, and vanilla JS
- Comprehensive documentation covering API, customization, and legal compliance
- GDPR compliant by default with enhanced tracking only on explicit consent

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Ole-Morten Duesund 2025-09-08 12:59:47 +02:00
commit 2d693605cf
4 changed files with 1130 additions and 0 deletions

128
CLAUDE.md Normal file
View file

@ -0,0 +1,128 @@
# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Repository Information
- **Git Repository**: ssh://git@kode.naiv.no:2222/olemd/gdpr.git
- **Forgejo Server**: https://kode.naiv.no
- **Owner**: olemd
## Project Overview
This is a GDPR-compliant optional tracking solution that provides a privacy-first approach to website analytics. The core concept is "minimal tracking by default, enhanced tracking by consent" - users start with privacy-protected minimal tracking and can opt-in to enhanced features.
## Architecture
### Core Components
**GDPRTrackingConsent Class** (`index.html`)
- Main JavaScript class that manages consent state and UI interactions
- Handles localStorage persistence with key 'gdpr-tracking-consent'
- Integrates with Google Analytics consent modes (`analytics_storage`, `ad_storage`, `personalization_storage`)
- Manages cookie cleanup for tracking cookies (`_ga`, `_gid`, `_gat`, `_fbp`, `_fbc`)
- Fires custom events (`trackingModeChanged`) for external integrations
**Two-Mode System**
- **Minimal Mode**: Essential cookies only, anonymized analytics, consent denied by default
- **Enhanced Mode**: Full tracking enabled only after explicit user consent
### Key Files
- `index.html` - Complete demo with hero section, feature explanations, and live status indicator
- `integration-example.js` - Production-ready integration examples for React, Vue, WordPress, and vanilla JS
- `README.md` - Documentation covering API, customization, and legal compliance
## Development Commands
### Repository Operations
```bash
# Clone the repository
git clone ssh://git@kode.naiv.no:2222/olemd/gdpr.git
# Use fj (Forgejo CLI) for repository management
fj repo view olemd/gdpr
fj issue list
fj pr list
```
### Testing the Demo
```bash
# Open the demo in your browser
open index.html
# or
python3 -m http.server 8000 # Then visit http://localhost:8000
```
### Git Workflow
```bash
# Standard git operations work with the Forgejo server
git push origin main
git pull origin main
```
### Integration Testing
The solution integrates with Google Analytics via consent modes:
```javascript
// Check current consent status
localStorage.getItem('gdpr-tracking-consent') === 'true'
// Listen for mode changes
document.addEventListener('trackingModeChanged', (e) => {
console.log('Mode:', e.detail.mode); // 'minimal' or 'enhanced'
});
```
## Key Implementation Details
### Consent Flow
1. Page loads with minimal tracking (GDPR compliant by default)
2. User sees "Plz trac me!" button in bottom-right
3. Clicking shows consent modal with clear explanation
4. User can enable enhanced tracking or dismiss
5. Status persisted in localStorage, toggleable anytime
### Google Analytics Integration
The solution expects Google Analytics to be initialized with consent mode:
```javascript
gtag('consent', 'default', {
'analytics_storage': 'denied',
'ad_storage': 'denied',
'personalization_storage': 'denied'
});
```
The button automatically calls `gtag('consent', 'update', {...})` when user changes preferences.
### Cookie Management
- Automatically cleans up tracking cookies when switching to minimal mode
- Uses domain-aware cookie deletion for cross-subdomain cleanup
- Preserves essential functionality cookies (`functionality_storage: 'granted'`)
## Customization Points
### UI Customization
- Button styling via CSS classes `.tracking-consent-btn` and `.tracking-consent-btn.enabled`
- Modal content in `.consent-modal-content`
- Status indicator in `.tracking-status`
### Behavioral Customization
- Change storage key by modifying `this.storageKey` in constructor
- Customize consent message in modal HTML
- Add additional tracking services in `enableEnhancedTracking()` method
### Framework Integration
The `integration-example.js` contains complete examples for:
- WordPress (functions.php and shortcode approaches)
- React (hooks-based component)
- Vue.js (composition API)
- Minified standalone snippet for any website
## Legal Compliance Notes
This implementation addresses technical requirements for:
- GDPR Article 7 (explicit consent)
- ePrivacy Directive cookie requirements
- CCPA transparency requirements
However, legal compliance requires consultation with legal experts for specific jurisdictions and use cases.

161
README.md Normal file
View file

@ -0,0 +1,161 @@
# GDPR Compliant Optional Tracking Button
A lightweight, user-friendly JavaScript solution for implementing GDPR-compliant optional tracking on websites. By default, only minimal tracking is enabled, and users can opt-in to enhanced tracking with a fun "Plz trac me!" button.
## Features
- 🔒 **GDPR Compliant by Default**: Minimal tracking until user consents
- 🎨 **Beautiful UI**: Gradient button with hover effects and smooth animations
- 📱 **Mobile Responsive**: Works perfectly on all device sizes
- ⚡ **Lightweight**: Pure vanilla JavaScript, no dependencies
- 🔧 **Easy Integration**: Drop-in solution for any website
- 🍪 **Cookie Management**: Automatic cleanup when tracking is disabled
- 📊 **Analytics Ready**: Google Analytics consent mode integration
## Demo
Open `gdpr-tracking-consent.html` in your browser to see the button in action!
## Quick Start
### Option 1: Standalone HTML (Recommended for testing)
```html
<!-- Copy the contents of gdpr-tracking-consent.html -->
<!-- Everything you need is in one file -->
```
### Option 2: Minified Snippet (Production ready)
```html
<!-- Add this anywhere in your HTML body -->
<div class="tracking-consent-container" style="position:fixed;bottom:20px;right:20px;z-index:1000">
<button id="trackingConsentBtn" class="tracking-consent-btn">
<span>📊</span>
<span id="btnText">Plz trac me!</span>
</button>
</div>
<script>
// Minified version available in integration-example.js
</script>
```
## How It Works
### Default State (GDPR Compliant)
- Only essential cookies are allowed
- Basic analytics with anonymized IP
- No personalization or ad tracking
- No cross-site tracking
### Enhanced Tracking (User Opt-in)
- Detailed page interactions
- User preferences for personalization
- Marketing campaign effectiveness
- Full Google Analytics features
## Integration Examples
### WordPress
```php
// Add to functions.php
function add_gdpr_tracking_consent() {
// Include the snippet
}
add_action('wp_footer', 'add_gdpr_tracking_consent');
```
### React
```jsx
import GDPRTrackingConsent from './GDPRTrackingConsent';
function App() {
return (
<div>
{/* Your app content */}
<GDPRTrackingConsent />
</div>
);
}
```
### Google Analytics Setup
```html
<script>
gtag('consent', 'default', {
'analytics_storage': 'denied',
'ad_storage': 'denied'
});
// The button will update these settings when user consents
</script>
```
## Customization
### Button Text
```javascript
// Change the button text
btnText.textContent = 'Enable Analytics';
```
### Styling
```css
.tracking-consent-btn {
/* Customize colors, position, size */
background: your-gradient;
bottom: 30px;
right: 30px;
}
```
### Consent Modal
```javascript
// Customize the consent message
const consentText = "Your custom consent message here";
```
## API Events
The button fires custom events you can listen to:
```javascript
document.addEventListener('trackingModeChanged', (e) => {
console.log('Tracking mode:', e.detail.mode); // 'minimal' or 'enhanced'
});
```
## Cookie Management
```javascript
// Access the consent status
const isTrackingEnabled = localStorage.getItem('gdpr-tracking-consent') === 'true';
// Programmatically enable/disable
window.trackingConsent.enableTracking();
window.trackingConsent.disableTracking();
```
## Browser Support
- Modern browsers (ES6+)
- Internet Explorer 11+ (with polyfills)
- All mobile browsers
## Files
- `gdpr-tracking-consent.html` - Complete demo with all features
- `integration-example.js` - Integration examples for different frameworks
- `README.md` - This documentation
## Legal Compliance
This solution helps with:
- ✅ GDPR Article 7 (Consent)
- ✅ ePrivacy Directive
- ✅ CCPA compliance
- ✅ Cookie Law compliance
**Note**: This is a technical implementation. Always consult with legal experts for complete GDPR compliance in your specific jurisdiction and use case.
## License
MIT License - Feel free to use in any project!

552
index.html Normal file
View file

@ -0,0 +1,552 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>🍪 Privacy-First Demo | GDPR Compliant Tracking</title>
<style>
* {
box-sizing: border-box;
}
body {
margin: 0;
padding: 0;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
min-height: 100vh;
color: #333;
}
.hero {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
min-height: 100vh;
text-align: center;
padding: 2rem;
position: relative;
}
.hero::before {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: rgba(255, 255, 255, 0.95);
backdrop-filter: blur(10px);
}
.hero-content {
position: relative;
z-index: 1;
max-width: 800px;
}
.hero h1 {
font-size: 3.5rem;
font-weight: 700;
margin: 0 0 1rem 0;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
-webkit-background-clip: text;
-webkit-text-fill-color: transparent;
background-clip: text;
}
.hero .subtitle {
font-size: 1.4rem;
color: #666;
margin-bottom: 2rem;
font-weight: 300;
}
.privacy-badge {
display: inline-flex;
align-items: center;
gap: 8px;
background: #e8f5e8;
color: #2e7d2e;
padding: 8px 16px;
border-radius: 20px;
font-size: 14px;
font-weight: 600;
margin-bottom: 2rem;
box-shadow: 0 2px 8px rgba(46, 125, 46, 0.1);
}
.demo-info {
background: white;
padding: 2rem;
border-radius: 16px;
box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
margin-top: 2rem;
text-align: left;
}
.demo-info h2 {
color: #333;
margin-top: 0;
display: flex;
align-items: center;
gap: 8px;
}
.feature-list {
display: grid;
grid-template-columns: repeat(auto-fit, minmax(250px, 1fr));
gap: 1rem;
margin: 1.5rem 0;
}
.feature {
display: flex;
align-items: center;
gap: 12px;
padding: 1rem;
background: #f8f9fa;
border-radius: 8px;
border-left: 4px solid #667eea;
}
.feature-icon {
font-size: 1.5rem;
min-width: 24px;
}
.tracking-status {
position: fixed;
top: 20px;
left: 20px;
background: rgba(255, 255, 255, 0.9);
backdrop-filter: blur(10px);
padding: 12px 20px;
border-radius: 25px;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.1);
z-index: 999;
display: flex;
align-items: center;
gap: 8px;
font-weight: 600;
font-size: 14px;
}
.status-dot {
width: 8px;
height: 8px;
border-radius: 50%;
background: #4caf50;
}
.status-dot.minimal {
background: #ff9800;
}
@media (max-width: 768px) {
.hero h1 {
font-size: 2.5rem;
}
.hero .subtitle {
font-size: 1.2rem;
}
.demo-info {
padding: 1.5rem;
}
.tracking-status {
position: static;
margin-bottom: 2rem;
}
}
.tracking-consent-container {
position: fixed;
bottom: 20px;
right: 20px;
z-index: 1000;
}
.tracking-consent-btn {
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
border: none;
padding: 12px 24px;
border-radius: 25px;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
font-size: 14px;
font-weight: 600;
cursor: pointer;
box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
transition: all 0.3s ease;
display: flex;
align-items: center;
gap: 8px;
}
.tracking-consent-btn:hover {
transform: translateY(-2px);
box-shadow: 0 6px 20px rgba(0, 0, 0, 0.3);
}
.tracking-consent-btn:active {
transform: translateY(0);
}
.tracking-consent-btn.enabled {
background: linear-gradient(135deg, #4facfe 0%, #00f2fe 100%);
}
.tracking-consent-btn.enabled::after {
content: "✓";
margin-left: 4px;
}
.tracking-icon {
font-size: 16px;
}
.consent-modal {
display: none;
position: fixed;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: rgba(0, 0, 0, 0.5);
z-index: 1001;
justify-content: center;
align-items: center;
}
.consent-modal-content {
background: white;
padding: 30px;
border-radius: 12px;
max-width: 500px;
margin: 20px;
box-shadow: 0 10px 30px rgba(0, 0, 0, 0.3);
}
.consent-modal h3 {
margin: 0 0 16px 0;
color: #333;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.consent-modal p {
margin: 0 0 20px 0;
color: #666;
line-height: 1.5;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.consent-modal-buttons {
display: flex;
gap: 12px;
justify-content: flex-end;
}
.consent-btn {
padding: 10px 20px;
border: none;
border-radius: 6px;
font-weight: 600;
cursor: pointer;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
}
.consent-btn.primary {
background: #667eea;
color: white;
}
.consent-btn.secondary {
background: #f5f5f5;
color: #333;
}
.consent-btn:hover {
opacity: 0.9;
}
</style>
</head>
<body>
<div class="tracking-status" id="trackingStatus">
<div class="status-dot minimal" id="statusDot"></div>
<span id="statusText">Privacy Mode: Minimal Tracking</span>
</div>
<div class="hero">
<div class="hero-content">
<div class="privacy-badge">
🔒 <span>GDPR Compliant by Default</span>
</div>
<h1>Privacy-First Demo</h1>
<p class="subtitle">
Experience truly optional tracking. Your privacy is protected by default,<br>
with enhanced features available only when <em>you</em> choose to enable them.
</p>
<div class="demo-info">
<h2>🎯 How It Works</h2>
<p>This demo shows how modern websites can respect your privacy while still providing great experiences:</p>
<div class="feature-list">
<div class="feature">
<span class="feature-icon">🔒</span>
<div>
<strong>Default: Privacy Protected</strong><br>
<small>Only essential cookies, anonymized analytics</small>
</div>
</div>
<div class="feature">
<span class="feature-icon">📊</span>
<div>
<strong>Optional: Enhanced Tracking</strong><br>
<small>Detailed analytics, personalization when you opt-in</small>
</div>
</div>
<div class="feature">
<span class="feature-icon">🎚️</span>
<div>
<strong>Full Control</strong><br>
<small>Toggle anytime with the button below</small>
</div>
</div>
<div class="feature">
<span class="feature-icon">🍪</span>
<div>
<strong>Smart Cookie Management</strong><br>
<small>Automatic cleanup when disabled</small>
</div>
</div>
</div>
<p><strong>Try it out!</strong> Click the colorful button in the bottom-right corner to see the consent flow in action. 👇</p>
</div>
</div>
</div>
<div class="tracking-consent-container">
<button id="trackingConsentBtn" class="tracking-consent-btn">
<span class="tracking-icon">📊</span>
<span id="btnText">Plz trac me!</span>
</button>
</div>
<div id="consentModal" class="consent-modal">
<div class="consent-modal-content">
<h3>Optional Enhanced Tracking</h3>
<p>
We respect your privacy! By default, we only use essential cookies and basic analytics.
If you'd like to help us improve our service with enhanced tracking (detailed analytics,
personalization, marketing cookies), you can opt in below.
</p>
<p>
<strong>What we'll track:</strong><br>
• Detailed page interactions<br>
• User preferences for personalization<br>
• Marketing campaign effectiveness<br>
• Enhanced usage analytics
</p>
<p>You can change your mind anytime by clicking the tracking button again.</p>
<div class="consent-modal-buttons">
<button class="consent-btn secondary" onclick="closeConsentModal()">No, thanks</button>
<button class="consent-btn primary" onclick="enableTracking()">Yes, track me!</button>
</div>
</div>
</div>
<script>
class GDPRTrackingConsent {
constructor() {
this.storageKey = 'gdpr-tracking-consent';
this.isTrackingEnabled = this.getConsentStatus();
this.init();
}
init() {
this.updateButtonState();
this.setupEventListeners();
if (this.isTrackingEnabled) {
this.enableEnhancedTracking();
} else {
this.enableMinimalTracking();
}
}
setupEventListeners() {
const btn = document.getElementById('trackingConsentBtn');
btn.addEventListener('click', () => {
if (this.isTrackingEnabled) {
this.showDisableConfirm();
} else {
this.showConsentModal();
}
});
const modal = document.getElementById('consentModal');
modal.addEventListener('click', (e) => {
if (e.target === modal) {
this.closeConsentModal();
}
});
}
getConsentStatus() {
const stored = localStorage.getItem(this.storageKey);
return stored === 'true';
}
setConsentStatus(status) {
localStorage.setItem(this.storageKey, status.toString());
this.isTrackingEnabled = status;
}
updateButtonState() {
const btn = document.getElementById('trackingConsentBtn');
const btnText = document.getElementById('btnText');
const statusText = document.getElementById('statusText');
const statusDot = document.getElementById('statusDot');
if (this.isTrackingEnabled) {
btn.classList.add('enabled');
btnText.textContent = 'Tracking ON';
statusText.textContent = 'Privacy Mode: Enhanced Tracking';
statusDot.className = 'status-dot';
} else {
btn.classList.remove('enabled');
btnText.textContent = 'Plz trac me!';
statusText.textContent = 'Privacy Mode: Minimal Tracking';
statusDot.className = 'status-dot minimal';
}
}
showConsentModal() {
document.getElementById('consentModal').style.display = 'flex';
}
closeConsentModal() {
document.getElementById('consentModal').style.display = 'none';
}
showDisableConfirm() {
if (confirm('Disable enhanced tracking? We\'ll switch back to minimal analytics only.')) {
this.disableTracking();
}
}
enableTracking() {
this.setConsentStatus(true);
this.updateButtonState();
this.closeConsentModal();
this.enableEnhancedTracking();
this.showNotification('Enhanced tracking enabled! Thanks for helping us improve.');
}
disableTracking() {
this.setConsentStatus(false);
this.updateButtonState();
this.enableMinimalTracking();
this.showNotification('Switched to minimal tracking. Your privacy is protected.');
}
enableMinimalTracking() {
console.log('🔒 GDPR Mode: Minimal tracking enabled');
if (typeof gtag !== 'undefined') {
gtag('consent', 'update', {
'analytics_storage': 'denied',
'ad_storage': 'denied',
'personalization_storage': 'denied',
'functionality_storage': 'granted'
});
}
this.cleanupEnhancedCookies();
this.fireCustomEvent('trackingModeChanged', { mode: 'minimal' });
}
enableEnhancedTracking() {
console.log('📊 Enhanced tracking enabled');
if (typeof gtag !== 'undefined') {
gtag('consent', 'update', {
'analytics_storage': 'granted',
'ad_storage': 'granted',
'personalization_storage': 'granted',
'functionality_storage': 'granted'
});
}
this.initEnhancedAnalytics();
this.fireCustomEvent('trackingModeChanged', { mode: 'enhanced' });
}
initEnhancedAnalytics() {
if (typeof gtag !== 'undefined') {
gtag('event', 'enhanced_tracking_enabled', {
'event_category': 'privacy',
'event_label': 'user_opted_in'
});
}
}
cleanupEnhancedCookies() {
const cookiesToRemove = ['_ga', '_gid', '_gat', '_fbp', '_fbc'];
cookiesToRemove.forEach(cookie => {
document.cookie = `${cookie}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/`;
document.cookie = `${cookie}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/; domain=.${window.location.hostname}`;
});
}
fireCustomEvent(eventName, data) {
const event = new CustomEvent(eventName, { detail: data });
document.dispatchEvent(event);
}
showNotification(message) {
const notification = document.createElement('div');
notification.style.cssText = `
position: fixed;
top: 20px;
right: 20px;
background: #4caf50;
color: white;
padding: 12px 20px;
border-radius: 6px;
z-index: 1002;
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
box-shadow: 0 4px 12px rgba(0,0,0,0.2);
`;
notification.textContent = message;
document.body.appendChild(notification);
setTimeout(() => {
notification.remove();
}, 3000);
}
}
function closeConsentModal() {
window.trackingConsent.closeConsentModal();
}
function enableTracking() {
window.trackingConsent.enableTracking();
}
document.addEventListener('DOMContentLoaded', () => {
window.trackingConsent = new GDPRTrackingConsent();
});
document.addEventListener('trackingModeChanged', (e) => {
console.log('Tracking mode changed to:', e.detail.mode);
});
</script>
</body>
</html>

289
integration-example.js Normal file
View file

@ -0,0 +1,289 @@
/**
* GDPR Tracking Consent - Integration Example
*
* This file shows how to integrate the GDPR tracking consent button
* into your existing website or application.
*/
// Standalone JavaScript snippet (minified version for production)
const gdprTrackingSnippet = `
<div class="tracking-consent-container" style="position:fixed;bottom:20px;right:20px;z-index:1000">
<button id="trackingConsentBtn" class="tracking-consent-btn" style="background:linear-gradient(135deg,#667eea 0%,#764ba2 100%);color:white;border:none;padding:12px 24px;border-radius:25px;font-family:-apple-system,BlinkMacSystemFont,'Segoe UI',Roboto,sans-serif;font-size:14px;font-weight:600;cursor:pointer;box-shadow:0 4px 15px rgba(0,0,0,0.2);transition:all 0.3s ease;display:flex;align-items:center;gap:8px">
<span style="font-size:16px">📊</span>
<span id="btnText">Plz trac me!</span>
</button>
</div>
<div id="consentModal" style="display:none;position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.5);z-index:1001;justify-content:center;align-items:center">
<div style="background:white;padding:30px;border-radius:12px;max-width:500px;margin:20px;box-shadow:0 10px 30px rgba(0,0,0,0.3)">
<h3 style="margin:0 0 16px 0;color:#333">Optional Enhanced Tracking</h3>
<p style="margin:0 0 20px 0;color:#666;line-height:1.5">We respect your privacy! By default, we only use essential cookies and basic analytics.</p>
<div style="display:flex;gap:12px;justify-content:flex-end">
<button onclick="window.trackingConsent.closeConsentModal()" style="padding:10px 20px;border:none;border-radius:6px;background:#f5f5f5;color:#333;cursor:pointer">No, thanks</button>
<button onclick="window.trackingConsent.enableTracking()" style="padding:10px 20px;border:none;border-radius:6px;background:#667eea;color:white;cursor:pointer">Yes, track me!</button>
</div>
</div>
</div>
<script>
class GDPRTrackingConsent{constructor(){this.storageKey='gdpr-tracking-consent';this.isTrackingEnabled=localStorage.getItem(this.storageKey)==='true';this.init()}init(){this.updateButtonState();document.getElementById('trackingConsentBtn').onclick=()=>{this.isTrackingEnabled?confirm('Disable enhanced tracking?')&&this.disableTracking():document.getElementById('consentModal').style.display='flex'};this.isTrackingEnabled?this.enableEnhancedTracking():this.enableMinimalTracking()}updateButtonState(){const btn=document.getElementById('trackingConsentBtn');const text=document.getElementById('btnText');if(this.isTrackingEnabled){btn.style.background='linear-gradient(135deg,#4facfe 0%,#00f2fe 100%)';text.textContent='Tracking ON'}else{btn.style.background='linear-gradient(135deg,#667eea 0%,#764ba2 100%)';text.textContent='Plz trac me!'}}enableTracking(){localStorage.setItem(this.storageKey,'true');this.isTrackingEnabled=true;this.updateButtonState();document.getElementById('consentModal').style.display='none';this.enableEnhancedTracking()}disableTracking(){localStorage.setItem(this.storageKey,'false');this.isTrackingEnabled=false;this.updateButtonState();this.enableMinimalTracking()}enableMinimalTracking(){console.log('🔒 GDPR Mode: Minimal tracking');if(typeof gtag!=='undefined'){gtag('consent','update',{analytics_storage:'denied',ad_storage:'denied'})}}enableEnhancedTracking(){console.log('📊 Enhanced tracking enabled');if(typeof gtag!=='undefined'){gtag('consent','update',{analytics_storage:'granted',ad_storage:'granted'})}}}window.trackingConsent=new GDPRTrackingConsent();
</script>`;
// Integration examples for different scenarios
// 1. WordPress Integration
const wordPressIntegration = {
// Add to functions.php
php: `
<?php
// Add GDPR tracking consent to WordPress footer
function add_gdpr_tracking_consent() {
?>
<!-- GDPR Tracking Consent Button -->
${gdprTrackingSnippet}
<?php
}
add_action('wp_footer', 'add_gdpr_tracking_consent');
?>`,
// Or as a WordPress shortcode
shortcode: `
<?php
function gdpr_tracking_shortcode() {
return '${gdprTrackingSnippet}';
}
add_shortcode('gdpr_tracking', 'gdpr_tracking_shortcode');
?>
<!-- Usage: [gdpr_tracking] -->`
};
// 2. React Integration
const reactIntegration = `
import React, { useEffect, useState } from 'react';
const GDPRTrackingConsent = () => {
const [isTrackingEnabled, setIsTrackingEnabled] = useState(false);
const [showModal, setShowModal] = useState(false);
useEffect(() => {
const consent = localStorage.getItem('gdpr-tracking-consent') === 'true';
setIsTrackingEnabled(consent);
if (consent) {
enableEnhancedTracking();
} else {
enableMinimalTracking();
}
}, []);
const enableTracking = () => {
localStorage.setItem('gdpr-tracking-consent', 'true');
setIsTrackingEnabled(true);
setShowModal(false);
enableEnhancedTracking();
};
const disableTracking = () => {
if (window.confirm('Disable enhanced tracking?')) {
localStorage.setItem('gdpr-tracking-consent', 'false');
setIsTrackingEnabled(false);
enableMinimalTracking();
}
};
const enableMinimalTracking = () => {
console.log('🔒 GDPR Mode: Minimal tracking');
if (typeof window.gtag !== 'undefined') {
window.gtag('consent', 'update', {
'analytics_storage': 'denied',
'ad_storage': 'denied'
});
}
};
const enableEnhancedTracking = () => {
console.log('📊 Enhanced tracking enabled');
if (typeof window.gtag !== 'undefined') {
window.gtag('consent', 'update', {
'analytics_storage': 'granted',
'ad_storage': 'granted'
});
}
};
return (
<>
<div style={{position: 'fixed', bottom: '20px', right: '20px', zIndex: 1000}}>
<button
onClick={isTrackingEnabled ? disableTracking : () => setShowModal(true)}
style={{
background: isTrackingEnabled
? 'linear-gradient(135deg, #4facfe 0%, #00f2fe 100%)'
: 'linear-gradient(135deg, #667eea 0%, #764ba2 100%)',
color: 'white',
border: 'none',
padding: '12px 24px',
borderRadius: '25px',
cursor: 'pointer'
}}
>
📊 {isTrackingEnabled ? 'Tracking ON' : 'Plz trac me!'}
</button>
</div>
{showModal && (
<div style={{
position: 'fixed', top: 0, left: 0, width: '100%', height: '100%',
background: 'rgba(0,0,0,0.5)', zIndex: 1001, display: 'flex',
justifyContent: 'center', alignItems: 'center'
}}>
<div style={{
background: 'white', padding: '30px', borderRadius: '12px',
maxWidth: '500px', margin: '20px'
}}>
<h3>Optional Enhanced Tracking</h3>
<p>We respect your privacy! Enable enhanced tracking to help us improve.</p>
<div>
<button onClick={() => setShowModal(false)}>No, thanks</button>
<button onClick={enableTracking}>Yes, track me!</button>
</div>
</div>
</div>
)}
</>
);
};
export default GDPRTrackingConsent;`;
// 3. Vue.js Integration
const vueIntegration = `
<template>
<div>
<div class="tracking-consent-container">
<button @click="handleButtonClick" class="tracking-consent-btn" :class="{ enabled: isTrackingEnabled }">
<span>📊</span>
<span>{{ isTrackingEnabled ? 'Tracking ON' : 'Plz trac me!' }}</span>
</button>
</div>
<div v-if="showModal" class="consent-modal" @click.self="showModal = false">
<div class="consent-modal-content">
<h3>Optional Enhanced Tracking</h3>
<p>We respect your privacy! Enable enhanced tracking to help us improve.</p>
<div>
<button @click="showModal = false">No, thanks</button>
<button @click="enableTracking">Yes, track me!</button>
</div>
</div>
</div>
</div>
</template>
<script>
export default {
data() {
return {
isTrackingEnabled: false,
showModal: false
};
},
mounted() {
this.isTrackingEnabled = localStorage.getItem('gdpr-tracking-consent') === 'true';
this.isTrackingEnabled ? this.enableEnhancedTracking() : this.enableMinimalTracking();
},
methods: {
handleButtonClick() {
if (this.isTrackingEnabled) {
this.disableTracking();
} else {
this.showModal = true;
}
},
enableTracking() {
localStorage.setItem('gdpr-tracking-consent', 'true');
this.isTrackingEnabled = true;
this.showModal = false;
this.enableEnhancedTracking();
},
disableTracking() {
if (confirm('Disable enhanced tracking?')) {
localStorage.setItem('gdpr-tracking-consent', 'false');
this.isTrackingEnabled = false;
this.enableMinimalTracking();
}
},
enableMinimalTracking() {
console.log('🔒 GDPR Mode: Minimal tracking');
if (typeof gtag !== 'undefined') {
gtag('consent', 'update', { 'analytics_storage': 'denied', 'ad_storage': 'denied' });
}
},
enableEnhancedTracking() {
console.log('📊 Enhanced tracking enabled');
if (typeof gtag !== 'undefined') {
gtag('consent', 'update', { 'analytics_storage': 'granted', 'ad_storage': 'granted' });
}
}
}
};
</script>`;
// 4. Google Analytics Integration
const googleAnalyticsSetup = `
<!-- Google Analytics with GDPR Consent -->
<script async src="https://www.googletagmanager.com/gtag/js?id=GA_MEASUREMENT_ID"></script>
<script>
window.dataLayer = window.dataLayer || [];
function gtag(){dataLayer.push(arguments);}
gtag('js', new Date());
// Initialize with minimal consent (GDPR compliant by default)
gtag('consent', 'default', {
'analytics_storage': 'denied',
'ad_storage': 'denied',
'personalization_storage': 'denied',
'functionality_storage': 'granted',
'security_storage': 'granted'
});
gtag('config', 'GA_MEASUREMENT_ID', {
anonymize_ip: true,
allow_google_signals: false,
allow_ad_personalization_signals: false
});
</script>`;
// 5. Cookie Management Integration
const cookieManagement = `
// Cookie utility functions for GDPR compliance
class GDPRCookieManager {
static setCookie(name, value, days = 365, sameSite = 'Lax') {
const expires = new Date(Date.now() + days * 864e5).toUTCString();
document.cookie = \`\${name}=\${value}; expires=\${expires}; path=/; SameSite=\${sameSite}\`;
}
static getCookie(name) {
return document.cookie.split('; ').reduce((r, v) => {
const parts = v.split('=');
return parts[0] === name ? decodeURIComponent(parts[1]) : r;
}, '');
}
static deleteCookie(name) {
document.cookie = \`\${name}=; expires=Thu, 01 Jan 1970 00:00:00 GMT; path=/\`;
}
static cleanupTrackingCookies() {
const trackingCookies = ['_ga', '_gid', '_gat', '_fbp', '_fbc', '_hjid'];
trackingCookies.forEach(cookie => this.deleteCookie(cookie));
}
}`;
// Export all integration examples
module.exports = {
gdprTrackingSnippet,
wordPressIntegration,
reactIntegration,
vueIntegration,
googleAnalyticsSetup,
cookieManagement
};