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:
commit
2d693605cf
4 changed files with 1130 additions and 0 deletions
128
CLAUDE.md
Normal file
128
CLAUDE.md
Normal 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
161
README.md
Normal 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
552
index.html
Normal 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
289
integration-example.js
Normal 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
|
||||||
|
};
|
||||||
Loading…
Add table
Add a link
Reference in a new issue