Claude-skill-registry cloudflare-zaraz

Server-side tag management for third-party tools with edge execution, privacy controls, and near-zero performance impact

install
source · Clone the upstream repo
git clone https://github.com/majiayu000/claude-skill-registry
Claude Code · Install into ~/.claude/skills/
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"
manifest: skills/data/cloudflare-zaraz/SKILL.md
source content

Cloudflare 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

  1. Navigate to Zaraz > Tools configuration in Cloudflare dashboard
  2. Select Third-party tools > Add new tool
  3. Browse the tools catalog and select your tool
  4. Configure tool-specific settings
  5. Set up actions with firing triggers
  6. Save configuration

Automatic Action Types

When tools support automatic actions:

  • Pageviews: Track all page loads automatically
  • Events: Monitor via
    zaraz.track()
    Web API
  • E-Commerce: Process transactions via
    zaraz.ecommerce()
    API

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:

ScopePersistenceUse Case
page
Current page onlyPage-specific context
session
Browser sessionUser session data
persist
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:

PropertyDescription
product_id
Unique identifier
sku
Stock keeping unit
name
Product name
brand
Brand name
category
Product category
variant
Product variant
price
Unit price
quantity
Number of items
coupon
Applied coupon
position
List position

Order Properties:

PropertyDescription
order_id
Order identifier
checkout_id
Checkout identifier
total
Total amount
revenue
Revenue (excl. shipping/tax)
shipping
Shipping cost
tax
Tax amount
discount
Discount applied
currency
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:

MethodDescription
get(purposeId)
Get consent for specific purpose
set(preferences)
Update consent for purposes
getAll()
Get all consent statuses
setAll(status)
Set all purposes
getAllCheckboxes()
Get checkbox states
setCheckboxes(states)
Update checkboxes
setAllCheckboxes(state)
Set all checkboxes
sendQueuedEvents()
Send blocked events after consent

Properties:

PropertyDescription
modal
Show/hide consent modal
purposes
Read-only purpose definitions
APIReady
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

PropertyDescription
Event NameName from zaraz.track()
Track PropertyValues from eventProperties or zaraz.set()

Page Properties

PropertyDescription
Page encodingDocument character encoding
Page referrerReferring URL
Page titleDocument title
Query paramSpecific URL parameter
URL (various)host, hostname, origin, pathname, port, protocol

Device Properties

PropertyDescription
Browser engine/name/versionBrowser details
Device typeDesktop, mobile, tablet
Device CPUProcessor architecture
LanguageBrowser language
ResolutionScreen dimensions
ViewportBrowser viewport size
OS name/versionOperating system
User-agentFull UA string
IP addressVisitor IP

Location Properties

PropertyDescription
CityVisitor city
ContinentGeographic continent
CountryCountry code
EUEU membership (1/0)
RegionRegion name
Region codeISO 3166-2 code
TimezoneVisitor timezone

Miscellaneous

PropertyDescription
Random numberUnique per request
Timestamp (ms/s)Unix timestamp
CookieBrowser cookie value

Data Layer Compatibility

Migrate from Google Tag Manager without code changes.

Enable Compatibility Mode

  1. Navigate to Zaraz > Settings
  2. 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

  1. Create Worker in Cloudflare dashboard or via Wrangler
  2. Navigate to Zaraz > Settings
  3. Select your Worker as Context Enricher

Settings Reference

Workflow

SettingDescription
Real-timeChanges publish immediately
Preview & PublishTest before deployment

Web API

SettingDescription
Debug KeyEnable Debug Mode
E-commerce trackingEnable zaraz.ecommerce()

Compatibility

SettingDescription
Data layer modeGTM dataLayer.push() support
SPA supportVirtual pageviews on URL change

Privacy

SettingDescription
Remove query paramsStrip URL parameters
Trim IP addressesRemove before sending to tools
Hide user-agentSanitize sensitive details
Hide referrerHide external referrers
Cookie domainCustom cookie domain

Injection

SettingDescription
Auto-injectLoad Zaraz automatically
Iframe injectionInject into iframes

Endpoints

SettingDescription
Custom pathsCustom script pathnames

Advanced

SettingDescription
Bot thresholdBlock suspected bot traffic
Context EnricherWorker for data enrichment
LogpushExport 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
  • Reddit
  • 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

MetricDescription
LoadsZaraz script loads
EventsTracked events (pageview, custom, ecommerce)
TriggersTrigger activations
ActionsAction executions
Server-side requestsHTTP status codes from third-party tools

Debug Mode

  1. Set Debug Key in Zaraz Settings
  2. Access via browser console
  3. View real-time event flow

Best Practices

Performance

  1. Use native integrations over Custom HTML
  2. Enable SPA support for single-page applications
  3. Use blocking triggers to prevent unnecessary actions
  4. Minimize Custom HTML - runs client-side

Privacy

  1. Enable IP trimming for GDPR compliance
  2. Configure consent purposes before enabling tools
  3. Use Context Enricher to redact sensitive data
  4. Hide referrers for cross-domain tracking protection

Migration from GTM

  1. Don't use GTM with Zaraz - loses optimization benefits
  2. Enable data layer compatibility for gradual migration
  3. Convert to native integrations over time
  4. 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

IssueSolution
zaraz is not defined
Verify domain is proxied, Auto Injection enabled
Browser extension can't detect toolsUse Debug Mode (server-side execution)
E-commerce returns undefinedEnable E-commerce tracking in Settings
Demographics missing in GAUse "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
})

Resources