npx claudepluginhub mukul975/privacy-data-protection-skills --plugin cookie-consent-skillsThis skill uses the workspace's default tool permissions.
Server-side tracking moves data collection from the user's browser to a server-controlled environment, providing greater control over what data is shared with third parties. Instead of loading third-party JavaScript directly in the browser (which sets third-party cookies and sends data to external servers without intermediation), a server-side container receives events from the client, processe...
Guides Next.js Cache Components and Partial Prerendering (PPR) with cacheComponents enabled. Implements 'use cache', cacheLife(), cacheTag(), revalidateTag(), static/dynamic optimization, and cache debugging.
Guides building MCP servers enabling LLMs to interact with external services via tools. Covers best practices, TypeScript/Node (MCP SDK), Python (FastMCP).
Generates original PNG/PDF visual art via design philosophy manifestos for posters, graphics, and static designs on user request.
Server-side tracking moves data collection from the user's browser to a server-controlled environment, providing greater control over what data is shared with third parties. Instead of loading third-party JavaScript directly in the browser (which sets third-party cookies and sends data to external servers without intermediation), a server-side container receives events from the client, processes them, and selectively forwards data to analytics and advertising endpoints. This architecture enables IP anonymization before data leaves the first-party infrastructure, consent-based routing of events, and reduced reliance on third-party cookies — directly supporting ePrivacy Directive Article 5(3) compliance and data minimization under GDPR Article 5(1)(c).
User's Browser
│
├── Client-side GTM container (minimal)
│ └── Sends events to first-party endpoint
│
▼
First-Party Server Endpoint
(https://data.pinnacle-ecommerce.com)
│
├── Server-side GTM container
│ ├── Validates consent state
│ ├── Anonymizes IP address
│ ├── Strips unnecessary identifiers
│ ├── Applies data minimization rules
│ │
│ ├── [If analytics consent granted]
│ │ └── Forward to Google Analytics 4
│ │
│ ├── [If advertising consent granted]
│ │ ├── Forward to Google Ads
│ │ ├── Forward to Meta Conversions API
│ │ └── Forward to other ad platforms
│ │
│ └── [If all consent denied]
│ └── Log aggregate pageview count only (no PII)
│
└── First-party server logs (retention: 90 days)
Server Container Hosting Options:
| Option | Provider | Monthly Cost (est.) | Latency | Control |
|---|---|---|---|---|
| Google Cloud Run | Google Cloud | EUR 50-200 | Low | High |
| AWS App Runner | Amazon Web Services | EUR 40-180 | Low | High |
| Custom Docker | Self-hosted | EUR 30-150 | Varies | Maximum |
| Stape.io | Managed service | EUR 20-100 | Low | Medium |
Pinnacle E-Commerce Ltd Configuration:
| Setting | Value |
|---|---|
| Server container URL | https://data.pinnacle-ecommerce.com |
| Custom domain | data.pinnacle-ecommerce.com (CNAME to container) |
| Container region | europe-west1 (Belgium) — co-located with EU users |
| Scaling | Min 1 instance, max 10 instances |
| SSL certificate | Let's Encrypt via managed certificate |
| First-party cookie domain | .pinnacle-ecommerce.com |
Using a subdomain of the main site domain ensures:
data.pinnacle-ecommerce.com are same-site, avoiding third-party cookie restrictionsDNS Configuration:
data.pinnacle-ecommerce.com CNAME server-container-abc123.run.app
Every event arriving at the server container includes the consent state from the client. The server validates this before forwarding:
Event Payload from Client:
{
"client_id": "1234567890.1709000000",
"event_name": "purchase",
"event_params": {
"transaction_id": "TXN-2026-0314-001",
"value": 149.99,
"currency": "EUR",
"items": [{"item_id": "SKU-001", "item_name": "Widget Pro"}]
},
"consent_state": {
"analytics_storage": "granted",
"ad_storage": "denied",
"ad_user_data": "denied",
"ad_personalization": "denied"
},
"user_agent": "Mozilla/5.0...",
"ip_address": "203.0.113.42"
}
Server-Side Routing Logic:
| Destination | Required Consent | Data Sent |
|---|---|---|
| GA4 Measurement Protocol | analytics_storage: granted | Event name, params, anonymized client_id |
| Google Ads Conversion API | ad_storage + ad_user_data: granted | Conversion data, gclid, hashed email |
| Meta Conversions API | ad_storage + ad_user_data: granted | Event data, fbp, hashed email/phone |
| Aggregate counter (internal) | None required | +1 to event type counter (no PII) |
The server container anonymizes IP addresses before forwarding to any third party:
Anonymization Rules:
| Method | Description | Use Case |
|---|---|---|
| IPv4 last octet zeroing | 203.0.113.42 → 203.0.113.0 | Standard GA4 anonymization |
| IPv6 last 80 bits zeroing | 2001:db8::1234:5678 → 2001:db8:: | IPv6 anonymization |
| Full IP removal | IP not forwarded at all | Maximum privacy (Meta CAPI) |
| Geolocation-only | Resolve to country/region, discard IP | Geo reporting without IP |
Pinnacle E-Commerce Ltd Policy:
The server container strips data before forwarding:
| Data Element | Retained for GA4 | Retained for Ads | Retained Internally |
|---|---|---|---|
| Full URL | Path only (no query params) | Path only | Full URL (90 days) |
| User agent | Reduced UA (SEC-CH-UA) | Reduced UA | Full UA (24 hours) |
| IP address | Anonymized | Anonymized | Full (24 hours) |
| Referrer | Domain only | Domain only | Full (90 days) |
| Client ID | GA client_id | gclid/wbraid only | Internal session ID |
| Email (hashed) | Not sent | SHA-256 hash | Not stored |
| Setting | Value |
|---|---|
| Measurement ID | G-PINNACLE123 |
| API Secret | Stored in Secret Manager |
| Send to | GA4 Measurement Protocol |
| IP anonymization | Enabled (default in GA4) |
| Client ID source | First-party _ga cookie |
| Session ID source | First-party ga* cookie |
| Setting | Value |
|---|---|
| Pixel ID | 123456789012345 |
| Access Token | Stored in Secret Manager |
| Event deduplication | event_id matches browser Pixel event_id |
| Data sent | Event name, event_time, action_source, hashed email |
| IP forwarding | Disabled |
| User agent forwarding | Reduced UA only |
The server container can set first-party cookies via Set-Cookie headers, giving them longer lifetimes than client-side JavaScript cookies (which Safari ITP caps at 7 days):
| Cookie | Set By | Duration | Purpose |
|---|---|---|---|
| _ga | Server (Set-Cookie header) | 2 years | GA4 client identifier |
| _ga_PINNACLE | Server (Set-Cookie header) | 2 years | GA4 session persistence |
| _fbc | Server (Set-Cookie header) | 90 days | Meta click identifier |
| _pin_sess | Server (Set-Cookie header) | 30 minutes | Internal session tracking |
All cookies above are set only when the corresponding consent category is granted.
| Metric | Target | Alert Threshold |
|---|---|---|
| Request latency (p99) | < 200ms | > 500ms |
| Error rate | < 0.1% | > 1% |
| Event throughput | Baseline +/- 20% | > 30% deviation |
| Consent validation failures | 0 | > 0 |
| Forwarding failures (GA4) | < 0.5% | > 2% |
| Forwarding failures (Meta) | < 1% | > 5% |
Monthly audit of server-side tracking: