Claude-skill-registry cloudflare-zaraz
Server-side tag management for third-party tools with edge execution, privacy controls, and near-zero performance impact
git clone https://github.com/majiayu000/claude-skill-registry
T=$(mktemp -d) && git clone --depth=1 https://github.com/majiayu000/claude-skill-registry "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/data/cloudflare-zaraz" ~/.claude/skills/majiayu000-claude-skill-registry-cloudflare-zaraz && rm -rf "$T"
skills/data/cloudflare-zaraz/SKILL.mdCloudflare Zaraz
Server-side tag management platform that loads third-party tools at Cloudflare's edge, eliminating client-side performance impact while providing privacy controls and consent management.
Overview
Cloudflare Zaraz offloads third-party tools (analytics, advertising pixels, chatbots, marketing automation) to the cloud, executing at the edge rather than in the browser. This architecture delivers near-zero performance impact while enhancing security and privacy.
Key Benefits
- Performance: Load multiple tools with minimal client impact
- Privacy: Built-in IP anonymization, referrer hiding, user-agent trimming
- Security: Server-side execution reduces attack surface
- Consent: Integrated Consent Management Platform (CMP)
- Simplicity: No code changes needed for most integrations
Getting Started
Prerequisites
- Website proxied through Cloudflare (recommended)
- At least one tool configured in Zaraz
- Auto-inject script enabled (default)
Adding Third-Party Tools
- Navigate to Zaraz > Tools configuration in Cloudflare dashboard
- Select Third-party tools > Add new tool
- Browse the tools catalog and select your tool
- Configure tool-specific settings
- Set up actions with firing triggers
- Save configuration
Automatic Action Types
When tools support automatic actions:
- Pageviews: Track all page loads automatically
- Events: Monitor via
Web APIzaraz.track() - E-Commerce: Process transactions via
APIzaraz.ecommerce()
Web API
The Zaraz Web API enables programmatic control from anywhere in the
<body> tag.
zaraz.track()
Track custom events and user actions.
// Syntax zaraz.track(eventName, [eventProperties]) // Basic event zaraz.track("button_click") // Event with properties zaraz.track("purchase", { value: 200, currency: "USD", product_id: "SKU-123" }) // Async usage await zaraz.track("signup_complete", { plan: "premium" })
Common Use Cases:
- User actions (sign-ups, button clicks, purchases)
- Page interactions (widget loads, element impressions)
- Form submissions
Accessing Properties in Triggers:
{{ client.value }} {{ client.`product_id` }} // Use backticks for special characters
zaraz.set()
Store variables for use across all events without repetition.
// Syntax zaraz.set(key, value, [options]) // Page scope (cleared on navigation) zaraz.set("page_category", "blog", { scope: "page" }) // Session scope (persists during session) zaraz.set("user_tier", "premium", { scope: "session" }) // Persist scope (localStorage, survives sessions) - DEFAULT zaraz.set("user_id", "12345", { scope: "persist" }) zaraz.set("user_id", "12345") // Same as above // Unset a variable zaraz.set("user_id", undefined)
Scope Options:
| Scope | Persistence | Use Case |
|---|---|---|
| Current page only | Page-specific context |
| Browser session | User session data |
| localStorage (default) | Cross-session identity |
zaraz.ecommerce()
Track e-commerce events with standardized data structure.
// Syntax zaraz.ecommerce(eventName, eventProperties) // Product viewed zaraz.ecommerce("Product Viewed", { product_id: "507f1f77", sku: "G-32", name: "Monopoly", price: 18.99, category: "Games" }) // Add to cart zaraz.ecommerce("Product Added", { product_id: "507f1f77", name: "Monopoly", price: 18.99, quantity: 1 }) // Order completed zaraz.ecommerce("Order Completed", { order_id: "50314b8e", total: 27.50, revenue: 25.00, shipping: 3.00, tax: 2.00, currency: "USD", products: [ { product_id: "507f1f77", name: "Monopoly", price: 18.99, quantity: 1 } ] })
Supported Events (18 total):
- Product List Viewed, Products Searched
- Product Clicked, Product Viewed, Product Added, Product Removed
- Product Added to Wishlist
- Cart Viewed
- Checkout Started, Checkout Step Viewed, Checkout Step Completed
- Payment Info Entered, Shipping Info Entered
- Order Completed, Order Updated, Order Refunded, Order Cancelled
- Clicked Promotion, Viewed Promotion
Product Properties:
| Property | Description |
|---|---|
| Unique identifier |
| Stock keeping unit |
| Product name |
| Brand name |
| Product category |
| Product variant |
| Unit price |
| Number of items |
| Applied coupon |
| List position |
Order Properties:
| Property | Description |
|---|---|
| Order identifier |
| Checkout identifier |
| Total amount |
| Revenue (excl. shipping/tax) |
| Shipping cost |
| Tax amount |
| Discount applied |
| Currency code |
Compatible Tools:
- Google Analytics 4
- Google Analytics (Universal)
- Facebook Pixel
- Bing
- Pinterest Conversions API
- TikTok
- Amplitude
- Branch
SPA Support
For Single Page Applications, Zaraz automatically tracks virtual pageviews when URLs change (enable in Settings).
// Manual SPA pageview (advanced use) zaraz.spaPageview()
Triggers
Triggers define conditions for action execution.
Match Rule
Compare variables against match strings.
Variables Available:
- Event Name
- URL components (pathname, host, query)
- Cookies
- Device Properties
- Page Properties
Match Operations:
- Equals / Does not equal
- Contains / Does not contain
- Starts with / Ends with
- Matches regex / Does not match regex
- Greater than / Less than
Click Listener
Monitor clicks using CSS selectors or XPath.
/* CSS Examples */ #submit-button /* ID selector */ .cta-button /* Class selector */ button[type="submit"] /* Attribute selector */
Parameters:
- Selector: CSS selector or XPath expression
- Wait for actions: Delay navigation (ms) to ensure requests complete
Form Submission
Track form submissions with optional validation.
/* Form selector */ #checkout-form form[name="contact"]
Parameters:
- Selector: CSS selector for form
- Validate: Only trigger on valid submissions
Element Visibility
Fire when elements become visible in viewport.
/* Visibility triggers */ #promo-banner .video-player
Scroll Depth
Trigger at scroll thresholds.
100px /* Fixed pixel value */ 50% /* Viewport percentage */
Timer
Execute after intervals.
Parameters:
- Interval: Milliseconds between executions
- Limit: Maximum executions (0 = unlimited)
Blocking Triggers
Prevent actions from firing under specific conditions.
Firing Trigger: Pageview Blocking Trigger: URL contains "/admin"
Key Points:
- Inverse of firing triggers
- Zaraz script still loads
- Must apply to each action individually
Consent Management
GDPR and ePrivacy Directive compliance through built-in CMP.
Key Concepts
Purpose: Reason for loading a tool (e.g., "Analytics", "Advertising") Consent: User permission to store/access cookies
Consent Storage
User preferences stored in first-party cookie:
{ "analytics": true, "advertising": false, "functional": true }
Consent API
// Wait for API ready document.addEventListener("zarazConsentAPIReady", () => { // Check specific purpose const analyticsConsent = zaraz.consent.get("analytics") // Get all consent statuses const allConsent = zaraz.consent.getAll() // Set consent for specific purposes zaraz.consent.set({ analytics: true, advertising: false }) // Accept or reject all zaraz.consent.setAll(true) // Accept all zaraz.consent.setAll(false) // Reject all // Show consent modal zaraz.consent.modal = true }) // Listen for consent changes document.addEventListener("zarazConsentChoicesUpdated", () => { console.log("User updated consent preferences") }) // Send queued events after consent zaraz.consent.sendQueuedEvents()
API Methods:
| Method | Description |
|---|---|
| Get consent for specific purpose |
| Update consent for purposes |
| Get all consent statuses |
| Set all purposes |
| Get checkbox states |
| Update checkboxes |
| Set all checkboxes |
| Send blocked events after consent |
Properties:
| Property | Description |
|---|---|
| Show/hide consent modal |
| Read-only purpose definitions |
| Boolean API availability |
Region-Based Consent
document.addEventListener("zarazConsentAPIReady", () => { // Show modal only for EU visitors if (zaraz.consent.purposes.analytics.region === "EU") { zaraz.consent.modal = true } else { zaraz.consent.setAll(true) } })
Properties Reference
Event Properties
| Property | Description |
|---|---|
| Event Name | Name from zaraz.track() |
| Track Property | Values from eventProperties or zaraz.set() |
Page Properties
| Property | Description |
|---|---|
| Page encoding | Document character encoding |
| Page referrer | Referring URL |
| Page title | Document title |
| Query param | Specific URL parameter |
| URL (various) | host, hostname, origin, pathname, port, protocol |
Device Properties
| Property | Description |
|---|---|
| Browser engine/name/version | Browser details |
| Device type | Desktop, mobile, tablet |
| Device CPU | Processor architecture |
| Language | Browser language |
| Resolution | Screen dimensions |
| Viewport | Browser viewport size |
| OS name/version | Operating system |
| User-agent | Full UA string |
| IP address | Visitor IP |
Location Properties
| Property | Description |
|---|---|
| City | Visitor city |
| Continent | Geographic continent |
| Country | Country code |
| EU | EU membership (1/0) |
| Region | Region name |
| Region code | ISO 3166-2 code |
| Timezone | Visitor timezone |
Miscellaneous
| Property | Description |
|---|---|
| Random number | Unique per request |
| Timestamp (ms/s) | Unix timestamp |
| Cookie | Browser cookie value |
Data Layer Compatibility
Migrate from Google Tag Manager without code changes.
Enable Compatibility Mode
- Navigate to Zaraz > Settings
- Enable Data layer compatibility mode
How It Works
// Existing GTM code dataLayer.push({ event: 'purchase', price: '24', currency: 'USD' }) // Automatically converted to zaraz.track('purchase', { price: '24', currency: 'USD' })
Note: E-commerce mapping not supported via dataLayer. Use
zaraz.ecommerce() instead.
Context Enricher
Enrich event data using Cloudflare Workers.
Basic Structure
export default { async fetch(request) { const { system, client } = await request.json() // Add weather data const weather = await fetch('https://api.weather.com/...') client.weather = await weather.json() // Redact email addresses for (const key in client) { if (typeof client[key] === 'string' && client[key].includes('@')) { client[key] = '[REDACTED]' } } return new Response(JSON.stringify({ system, client })) } }
Setup
- Create Worker in Cloudflare dashboard or via Wrangler
- Navigate to Zaraz > Settings
- Select your Worker as Context Enricher
Settings Reference
Workflow
| Setting | Description |
|---|---|
| Real-time | Changes publish immediately |
| Preview & Publish | Test before deployment |
Web API
| Setting | Description |
|---|---|
| Debug Key | Enable Debug Mode |
| E-commerce tracking | Enable zaraz.ecommerce() |
Compatibility
| Setting | Description |
|---|---|
| Data layer mode | GTM dataLayer.push() support |
| SPA support | Virtual pageviews on URL change |
Privacy
| Setting | Description |
|---|---|
| Remove query params | Strip URL parameters |
| Trim IP addresses | Remove before sending to tools |
| Hide user-agent | Sanitize sensitive details |
| Hide referrer | Hide external referrers |
| Cookie domain | Custom cookie domain |
Injection
| Setting | Description |
|---|---|
| Auto-inject | Load Zaraz automatically |
| Iframe injection | Inject into iframes |
Endpoints
| Setting | Description |
|---|---|
| Custom paths | Custom script pathnames |
Advanced
| Setting | Description |
|---|---|
| Bot threshold | Block suspected bot traffic |
| Context Enricher | Worker for data enrichment |
| Logpush | Export logs (Enterprise) |
Supported Tools
Analytics
- Amplitude
- Google Analytics (Universal)
- Google Analytics 4
- Mixpanel
- Segment
- Snowplow
- Pod Sights
Advertising
- Bing
- Facebook Pixel
- Floodlight
- Google Ads
- LinkedIn Insight
- Outbrain
- Pinterest / Pinterest Conversions API
- Quora
- Snapchat
- Taboola
- Tatari
- TikTok
- Twitter Pixel
Marketing
- Branch
- HubSpot
- Impact Radius
Recruiting
- Indeed
- iHire
- Upward
- ZipRecruiter
Custom Integrations
- Custom HTML
- Custom Image
- HTTP Request
Monitoring
Metrics Available
| Metric | Description |
|---|---|
| Loads | Zaraz script loads |
| Events | Tracked events (pageview, custom, ecommerce) |
| Triggers | Trigger activations |
| Actions | Action executions |
| Server-side requests | HTTP status codes from third-party tools |
Debug Mode
- Set Debug Key in Zaraz Settings
- Access via browser console
- View real-time event flow
Best Practices
Performance
- Use native integrations over Custom HTML
- Enable SPA support for single-page applications
- Use blocking triggers to prevent unnecessary actions
- Minimize Custom HTML - runs client-side
Privacy
- Enable IP trimming for GDPR compliance
- Configure consent purposes before enabling tools
- Use Context Enricher to redact sensitive data
- Hide referrers for cross-domain tracking protection
Migration from GTM
- Don't use GTM with Zaraz - loses optimization benefits
- Enable data layer compatibility for gradual migration
- Convert to native integrations over time
- Use zaraz.ecommerce() instead of dataLayer for e-commerce
Debugging
// Check if Zaraz is loaded if (typeof zaraz !== 'undefined') { console.log('Zaraz loaded successfully') } // Enable Debug Mode in console // Access real-time event monitoring
Common Issues
| Issue | Solution |
|---|---|
| Verify domain is proxied, Auto Injection enabled |
| Browser extension can't detect tools | Use Debug Mode (server-side execution) |
| E-commerce returns undefined | Enable E-commerce tracking in Settings |
| Demographics missing in GA | Use "Anonymize IP" instead of "Hide IP" |
Integration Examples
React E-commerce
import { useEffect } from 'react' function ProductPage({ product }) { useEffect(() => { // Track product view if (typeof zaraz !== 'undefined') { zaraz.ecommerce('Product Viewed', { product_id: product.id, name: product.name, price: product.price, category: product.category }) } }, [product]) const handleAddToCart = () => { if (typeof zaraz !== 'undefined') { zaraz.ecommerce('Product Added', { product_id: product.id, name: product.name, price: product.price, quantity: 1 }) } // Add to cart logic } return ( <div> <h1>{product.name}</h1> <button onClick={handleAddToCart}>Add to Cart</button> </div> ) }
Next.js with Consent
// components/ConsentBanner.jsx import { useEffect, useState } from 'react' export function ConsentBanner() { const [showBanner, setShowBanner] = useState(false) useEffect(() => { const handleReady = () => { const allConsent = zaraz.consent.getAll() if (Object.keys(allConsent).length === 0) { setShowBanner(true) } } document.addEventListener('zarazConsentAPIReady', handleReady) return () => document.removeEventListener('zarazConsentAPIReady', handleReady) }, []) const acceptAll = () => { zaraz.consent.setAll(true) setShowBanner(false) } const rejectAll = () => { zaraz.consent.setAll(false) setShowBanner(false) } if (!showBanner) return null return ( <div className="consent-banner"> <p>We use cookies to improve your experience.</p> <button onClick={acceptAll}>Accept All</button> <button onClick={rejectAll}>Reject All</button> <button onClick={() => zaraz.consent.modal = true}> Customize </button> </div> ) }
Vue.js Event Tracking
<template> <button @click="trackClick">{{ label }}</button> </template> <script setup> import { onMounted } from 'vue' const props = defineProps({ label: String, eventName: String, eventProps: Object }) onMounted(() => { if (typeof zaraz !== 'undefined') { zaraz.set('component_loaded', props.label, { scope: 'page' }) } }) function trackClick() { if (typeof zaraz !== 'undefined') { zaraz.track(props.eventName, props.eventProps) } } </script>
Checkout Flow
// Step 1: Checkout started zaraz.ecommerce('Checkout Started', { checkout_id: 'CHK-123', value: 50.00, currency: 'USD', products: cartItems }) // Step 2: Shipping info zaraz.ecommerce('Shipping Info Entered', { checkout_id: 'CHK-123', shipping_method: 'standard' }) // Step 3: Payment info zaraz.ecommerce('Payment Info Entered', { checkout_id: 'CHK-123', payment_method: 'credit_card' }) // Step 4: Order completed zaraz.ecommerce('Order Completed', { order_id: 'ORD-456', checkout_id: 'CHK-123', total: 53.00, revenue: 50.00, shipping: 3.00, tax: 0, currency: 'USD', products: cartItems })