Pirsch Event Tracking Setup | OpsBlu Docs

Pirsch Event Tracking Setup

Implement event tracking in Pirsch — custom events, ecommerce tracking, data layer configuration, and validation.

Overview

Event tracking in Pirsch allows you to monitor specific user interactions beyond standard pageviews. Whether it's button clicks, form submissions, downloads, video plays, or e-commerce transactions, Pirsch's event tracking provides privacy-conscious insights into how users engage with your website.

Unlike traditional analytics platforms that create detailed user profiles, Pirsch's event tracking maintains user privacy by aggregating events without persistent user identification. This enables you to understand user behavior patterns while staying compliant with privacy regulations like GDPR without requiring cookie consent banners.

Prerequisites

Before implementing event tracking, ensure you have the Pirsch extended script installed on your website. The basic Pirsch script only tracks pageviews; events require the extended version.

Install Extended Script

Replace the basic script with the extended version:

<script defer src="https://api.pirsch.io/pirsch-extended.js"
  id="pirschextendedjs"
  data-code="YOUR_IDENTIFICATION_CODE"></script>

Basic Event Tracking

Simple Event Syntax

Track an event with just a name:

pirsch('Button Click');

Event with Metadata

Add contextual information to events:

pirsch('Button Click', {
  meta: {
    button_name: 'Subscribe CTA',
    location: 'Header',
    color: 'Blue'
  }
});

Multiple Metadata Fields

Track rich event data:

pirsch('Video Played', {
  meta: {
    video_id: 'intro-2024',
    video_title: 'Product Introduction',
    duration: 120,
    position: 'hero-section',
    autoplay: false
  }
});

Common Event Patterns

Button Click Tracking

document.getElementById('cta-button').addEventListener('click', function() {
  pirsch('CTA Click', {
    meta: {
      button_text: this.textContent,
      button_id: this.id,
      page: window.location.pathname
    }
  });
});

Form Submission Tracking

document.getElementById('contact-form').addEventListener('submit', function(e) {
  pirsch('Form Submission', {
    meta: {
      form_name: 'Contact Form',
      form_id: this.id,
      fields_count: this.elements.length
    }
  });
});

Download Tracking

document.querySelectorAll('a[download]').forEach(link => {
  link.addEventListener('click', function() {
    pirsch('File Download', {
      meta: {
        file_name: this.getAttribute('download'),
        file_type: this.href.split('.').pop(),
        file_url: this.href
      }
    });
  });
});
document.querySelectorAll('a[href^="http"]').forEach(link => {
  // Only track external links
  if (!link.href.includes(window.location.hostname)) {
    link.addEventListener('click', function() {
      pirsch('Outbound Link', {
        meta: {
          destination: this.href,
          link_text: this.textContent,
          target: this.getAttribute('target')
        }
      });
    });
  }
});

Scroll Depth Tracking

let scrollMarkers = [25, 50, 75, 100];
let triggeredMarkers = new Set();

window.addEventListener('scroll', function() {
  let scrollPercent = (window.scrollY / (document.body.scrollHeight - window.innerHeight)) * 100;

  scrollMarkers.forEach(marker => {
    if (scrollPercent >= marker && !triggeredMarkers.has(marker)) {
      triggeredMarkers.add(marker);
      pirsch('Scroll Depth', {
        meta: {
          depth: marker + '%',
          page: window.location.pathname
        }
      });
    }
  });
});

Video Event Tracking

const video = document.getElementById('promo-video');

video.addEventListener('play', function() {
  pirsch('Video Play', {
    meta: {
      video_id: this.id,
      video_src: this.currentSrc
    }
  });
});

video.addEventListener('pause', function() {
  pirsch('Video Pause', {
    meta: {
      video_id: this.id,
      time_watched: Math.round(this.currentTime)
    }
  });
});

video.addEventListener('ended', function() {
  pirsch('Video Complete', {
    meta: {
      video_id: this.id,
      duration: Math.round(this.duration)
    }
  });
});

E-commerce Event Tracking

Add to Cart

function trackAddToCart(product) {
  pirsch('Add to Cart', {
    meta: {
      product_id: product.id,
      product_name: product.name,
      product_price: product.price,
      quantity: product.quantity,
      category: product.category
    }
  });
}

Purchase/Conversion

function trackPurchase(order) {
  pirsch('Purchase', {
    meta: {
      order_id: order.id,
      order_value: order.total,
      currency: order.currency,
      items_count: order.items.length,
      payment_method: order.payment_method
    }
  });
}

Product View

pirsch('Product View', {
  meta: {
    product_id: 'PRO-123',
    product_name: 'Premium Plan',
    product_price: 99.99,
    product_category: 'Subscriptions'
  }
});

Framework-Specific Implementations

React

import { useEffect } from 'react';

function SubscribeButton() {
  const handleClick = () => {
    // Track event
    if (window.pirsch) {
      window.pirsch('Subscribe Click', {
        meta: {
          component: 'SubscribeButton',
          plan: 'Premium'
        }
      });
    }

    // Handle subscription logic
    subscribe();
  };

  return (
    <button
      Subscribe Now
    </button>
  );
}

Vue.js

<template>
  <button @click="trackAndSubmit">Submit Form</button>
</template>

<script>
export default {
  methods: {
    trackAndSubmit() {
      if (window.pirsch) {
        window.pirsch('Form Submit', {
          meta: {
            form_type: 'contact',
            component: this.$options.name
          }
        });
      }
      this.submitForm();
    }
  }
}
</script>

Next.js

import { useRouter } from 'next/router';
import { useEffect } from 'react';

export default function MyComponent() {
  const router = useRouter();

  useEffect(() => {
    const handleRouteChange = (url) => {
      if (window.pirsch) {
        window.pirsch('Page View', {
          meta: {
            route: url,
            framework: 'Next.js'
          }
        });
      }
    };

    router.events.on('routeChangeComplete', handleRouteChange);
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, [router.events]);

  return <div>Content</div>;
}

Server-Side Event Tracking

Track events from your backend for critical actions:

// Node.js example
const axios = require('axios');

async function trackServerEvent(eventName, eventData) {
  try {
    await axios.post('https://api.pirsch.io/api/v1/event', {
      event_name: eventName,
      event_meta: eventData,
      url: 'https://example.com',
      ip: '192.168.1.1',
      user_agent: 'Server-Side Tracking'
    }, {
      headers: {
        'Authorization': `Bearer ${process.env.PIRSCH_ACCESS_TOKEN}`,
        'Content-Type': 'application/json'
      }
    });
  } catch (error) {
    console.error('Event tracking failed:', error);
  }
}

// Track server-side conversion
await trackServerEvent('API Signup', {
  plan: 'enterprise',
  value: 999,
  user_type: 'business'
});

Validation and Testing

Verify Event Tracking

  1. Check Script Load:
// Open browser console and run:
console.log(typeof pirsch !== 'undefined' ? 'Pirsch extended loaded' : 'Pirsch not loaded');
  1. Test Event Firing:
// Manually trigger test event in console:
pirsch('Test Event', { meta: { test: true } });
  1. Monitor Network Requests:
    • Open Developer Tools (F12)
    • Go to Network tab
    • Filter by "pirsch.io"
    • Trigger events and watch for POST requests to /api/v1/event

Dashboard Verification

  1. Wait 5-10 minutes for event processing
  2. Navigate to your Pirsch dashboard
  3. Go to Events section
  4. Verify your custom events appear in the list
  5. Check event metadata is captured correctly

Debug Mode

Add console logging for debugging:

function trackEvent(eventName, eventData) {
  console.log('Tracking event:', eventName, eventData);

  if (window.pirsch) {
    pirsch(eventName, eventData);
  } else {
    console.warn('Pirsch not loaded');
  }
}

Best Practices

  1. Consistent Naming: Use a clear, consistent naming convention for events

    • Good: "Button Click - CTA Subscribe"
    • Avoid: "click", "btn_clk", "subscribe_cta_button_clicked"
  2. Meaningful Metadata: Include context that helps analyze behavior

    • Include page location, element identifiers, and relevant values
    • Avoid personally identifiable information (PII)
  3. Don't Over-Track: Focus on meaningful interactions

    • Track conversions, engagement, and key user actions
    • Avoid tracking every mouse movement or trivial interaction
  4. Privacy First: Never include PII in event data

    • No: email addresses, names, IP addresses, user IDs
    • Yes: product IDs, categories, anonymous values
  5. Test Before Deploy: Verify events in development

    • Use browser console to test event firing
    • Check dashboard to confirm data appears correctly
  6. Document Your Events: Maintain an event tracking specification

    • List all tracked events and their metadata fields
    • Document why each event is tracked

Troubleshooting

Issue Cause Solution
Events not appearing Using basic script instead of extended Replace with pirsch-extended.js script
pirsch is not defined error Script not loaded or blocked Check browser console for loading errors; verify script URL
Event fires multiple times Multiple event listeners attached Use event delegation or ensure single listener attachment
Metadata missing in dashboard Incorrect meta structure Ensure metadata is within meta: {} object
Events not showing in dashboard Data processing delay Wait 5-10 minutes; check Events section not Pageviews
Server-side events failing Invalid token or endpoint Verify access token and use correct API endpoint
High event volume Tracking too many events Review and reduce event tracking to meaningful interactions
Events on wrong domain Using same code for multiple sites Ensure each domain has unique identification code

Event Naming Conventions

Use clear, hierarchical naming:

// Category - Action - Detail
pirsch('Ecommerce - Add to Cart - Premium Plan');
pirsch('Engagement - Video Play - Tutorial');
pirsch('Conversion - Signup - Free Trial');
pirsch('Navigation - Click - External Link');

Alternative Format

// Object - Action
pirsch('Button - Click');
pirsch('Form - Submit');
pirsch('Video - Complete');
pirsch('Download - Start');