Reddit Ads Event Tracking | OpsBlu Docs

Reddit Ads Event Tracking

Implement Reddit Pixel standard events and custom conversions for audience building, campaign optimization, and reporting.

Standard Events Overview

Reddit Pixel provides predefined standard events that align with common conversion actions. Using standard events enables better campaign optimization, audience creation, and reporting within Reddit Ads Manager.

Why Use Standard Events

  • Campaign Optimization: Reddit's algorithm optimizes delivery to users likely to complete standard events
  • Audience Building: Create retargeting and lookalike audiences based on standard events
  • Consistent Reporting: Standard events appear in predefined reports and dashboards
  • Cross-Platform Comparison: Align with industry-standard event names for multi-platform analysis

Reddit Standard Events

PageView

Description: Automatically tracked when pixel loads. Represents a page view on your website.

When to Use: Base pixel fires this automatically. No additional implementation required.

Implementation:

// Fired automatically by base pixel
rdt('track', 'PageView');

Parameters: None required

Use Cases:


Purchase

Description: Completed transaction or purchase event.

When to Use: Fire on order confirmation page after successful payment.

Implementation:

rdt('track', 'Purchase', {
  value: 149.99,              // Total purchase amount
  currency: 'USD',            // Three-letter currency code
  transactionId: 'ORDER_12345', // Unique order identifier
  itemCount: 3                // Number of items purchased
});

Required Parameters:

  • value (number) - Total purchase amount
  • currency (string) - Three-letter ISO currency code (USD, EUR, GBP, etc.)

Optional Parameters:

  • transactionId (string) - Unique order/transaction ID for deduplication
  • itemCount (number) - Total number of items in order
  • products (array) - Array of product objects with id, name, price

Best Practices:

  • Always include transactionId for accurate reporting and deduplication
  • Use decimal values: 149.99 not 14999
  • Set useDecimalCurrencyValues: true in pixel init
  • Fire only once per transaction to avoid duplicate counting

SignUp

Description: User registration or account creation event.

When to Use: Fire when user successfully creates an account.

Implementation:

rdt('track', 'SignUp');

Optional Parameters:

  • value (number) - Lifetime value estimate for new user
  • currency (string) - Currency for value

Use Cases:

  • Optimize campaigns for user acquisition
  • Build audiences of registered users
  • Track registration conversion rates

Lead

Description: Lead generation event (form submission, contact request, quote request).

When to Use: Fire when user submits lead form or requests information.

Implementation:

rdt('track', 'Lead');

Optional Parameters:

  • value (number) - Estimated lead value
  • currency (string) - Currency for value

Use Cases:

  • B2B lead generation campaigns
  • Demo request tracking
  • Contact form submissions
  • Quote requests

ViewContent

Description: User viewed content or product page.

When to Use: Fire on product detail pages, blog posts, or key content pages.

Implementation:

rdt('track', 'ViewContent', {
  value: 99.99,          // Product price or content value
  currency: 'USD',
  itemCount: 1
});

Optional Parameters:

  • value (number) - Product price or content value
  • currency (string) - Currency code
  • itemCount (number) - Quantity viewed

Use Cases:

  • Build product viewer audiences for retargeting
  • Track product detail page engagement
  • Measure content engagement from Reddit traffic

AddToCart

Description: Product added to shopping cart.

When to Use: Fire when user clicks "Add to Cart" button.

Implementation:

rdt('track', 'AddToCart', {
  value: 99.99,
  currency: 'USD',
  itemCount: 1
});

Optional Parameters:

  • value (number) - Product price
  • currency (string) - Currency code
  • itemCount (number) - Quantity added

Use Cases:

  • Create cart abandonment retargeting audiences
  • Optimize for add-to-cart actions
  • Track funnel progression from view to cart

Description: User performed a search on your site.

When to Use: Fire when user completes a site search.

Implementation:

rdt('track', 'Search');

Optional Parameters:

  • None defined

Use Cases:

  • Track search engagement from Reddit traffic
  • Build audiences of active searchers
  • Measure user intent and product discovery

Custom Event

Description: Any custom business event not covered by standard events.

When to Use: Track unique business actions specific to your conversion funnel.

Implementation:

rdt('track', 'Custom', {
  customEventName: 'StartFreeTrial',
  value: 0,
  currency: 'USD'
});

Parameters:

  • customEventName (string) - Descriptive name for custom event
  • Additional custom parameters as needed

Event Tracking Examples

Ecommerce Purchase Flow

Product Detail Page:

rdt('track', 'ViewContent', {
  value: 99.99,
  currency: 'USD',
  itemCount: 1
});

Add to Cart:

document.getElementById('add-to-cart').addEventListener('click', function() {
  rdt('track', 'AddToCart', {
    value: parseFloat(productPrice),
    currency: 'USD',
    itemCount: parseInt(quantity)
  });
});

Order Confirmation:

rdt('track', 'Purchase', {
  value: 149.99,
  currency: 'USD',
  transactionId: 'ORDER_12345',
  itemCount: 3
});

Lead Generation Flow

Landing Page:

rdt('track', 'PageView');

Form Submission:

document.getElementById('lead-form').addEventListener('submit', function(e) {
  rdt('track', 'Lead');
});

SaaS Signup Flow

Pricing Page:

rdt('track', 'ViewContent');

Start Signup:

rdt('track', 'Custom', {
  customEventName: 'StartSignup'
});

Complete Registration:

rdt('track', 'SignUp');

Start Free Trial:

rdt('track', 'Custom', {
  customEventName: 'StartFreeTrial',
  value: 0,
  currency: 'USD'
});

Paid Subscription:

rdt('track', 'Purchase', {
  value: 29.99,
  currency: 'USD',
  transactionId: 'SUB_' + userId + '_' + Date.now()
});

Dynamic Event Parameters

Using Data Attributes

HTML:

<button
  class="add-to-cart"
  data-product-id="SKU_123"
  data-product-price="99.99"
  data-product-name="Widget Pro"
>
  Add to Cart
</button>

JavaScript:

document.querySelectorAll('.add-to-cart').forEach(button => {
  button.addEventListener('click', function() {
    const productId = this.dataset.productId;
    const productPrice = parseFloat(this.dataset.productPrice);
    const productName = this.dataset.productName;

    rdt('track', 'AddToCart', {
      value: productPrice,
      currency: 'USD',
      itemCount: 1
    });
  });
});

Server-Side Rendering

PHP Example:

<script>
rdt('track', 'Purchase', {
  value: <?php echo $order_total; ?>,
  currency: '<?php echo $order_currency; ?>',
  transactionId: '<?php echo $order_id; ?>',
  itemCount: <?php echo $order_item_count; ?>
});
</script>

Node.js/EJS Example:

<script>
rdt('track', 'Purchase', {
  value: <%= orderTotal %>,
  currency: '<%= orderCurrency %>',
  transactionId: '<%= orderId %>',
  itemCount: <%= itemCount %>
});
</script>

Google Tag Manager Implementation

DataLayer Push

Ecommerce Purchase:

// Push to dataLayer on purchase
dataLayer.push({
  'event': 'purchase',
  'transactionId': 'ORDER_12345',
  'transactionTotal': 149.99,
  'transactionCurrency': 'USD',
  'itemCount': 3
});

GTM Custom HTML Tag:

<script>
rdt('track', 'Purchase', {
  value: {{Transaction Total}},
  currency: {{Transaction Currency}},
  transactionId: {{Transaction ID}},
  itemCount: {{Item Count}}
});
</script>

Trigger: Custom Event equals purchase

Form Submission

DataLayer Push:

document.getElementById('lead-form').addEventListener('submit', function(e) {
  dataLayer.push({
    'event': 'leadFormSubmit'
  });
});

GTM Tag:

<script>
rdt('track', 'Lead');
</script>

Trigger: Custom Event equals leadFormSubmit

Single Page Application (SPA) Tracking

React Example

import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';

function AnalyticsProvider({ children }) {
  const location = useLocation();

  useEffect(() => {
    // Track page view on route change
    if (window.rdt) {
      window.rdt('track', 'PageView');
    }
  }, [location]);

  return children;
}

// Track purchase
function CheckoutSuccess({ order }) {
  useEffect(() => {
    if (window.rdt && order) {
      window.rdt('track', 'Purchase', {
        value: order.total,
        currency: order.currency,
        transactionId: order.id,
        itemCount: order.items.length
      });
    }
  }, [order]);

  return <div>Order confirmed!</div>;
}

Vue.js Example

// router/index.js
import { createRouter } from 'vue-router';

const router = createRouter({
  // ... routes
});

router.afterEach((to, from) => {
  // Track page view on navigation
  if (window.rdt) {
    window.rdt('track', 'PageView');
  }
});

// Component for tracking purchase
export default {
  name: 'OrderConfirmation',
  props: ['order'],
  mounted() {
    if (window.rdt && this.order) {
      window.rdt('track', 'Purchase', {
        value: this.order.total,
        currency: this.order.currency,
        transactionId: this.order.id,
        itemCount: this.order.items.length
      });
    }
  }
};

Advanced Event Patterns

Event with User Identification

rdt('track', 'Purchase', {
  value: 149.99,
  currency: 'USD',
  transactionId: 'ORDER_12345',
  itemCount: 3,
  email: hashEmail(userEmail),  // Hashed email for advanced matching
  externalId: userId             // Your internal user ID
});

function hashEmail(email) {
  // Use crypto.subtle.digest or library for SHA-256 hashing
  // Return hashed value
}

Conditional Event Tracking

// Only track if value exceeds threshold
if (orderTotal > 100) {
  rdt('track', 'Purchase', {
    value: orderTotal,
    currency: 'USD',
    transactionId: orderId
  });
}

// Track different events based on user type
if (isNewUser) {
  rdt('track', 'SignUp');
} else {
  rdt('track', 'Custom', {
    customEventName: 'RepeatPurchase'
  });
}

Throttled Event Tracking

// Debounce search tracking
let searchTimeout;
document.getElementById('search-input').addEventListener('input', function(e) {
  clearTimeout(searchTimeout);
  searchTimeout = setTimeout(() => {
    if (e.target.value.length > 2) {
      rdt('track', 'Search');
    }
  }, 500);
});

Event Validation

Browser Console Testing

// Check if pixel loaded
if (typeof rdt !== 'undefined') {
  console.log('Reddit Pixel loaded');

  // Fire test event
  rdt('track', 'Purchase', {
    value: 1.00,
    currency: 'USD',
    transactionId: 'TEST_' + Date.now()
  });

  console.log('Test event fired');
} else {
  console.error('Reddit Pixel not loaded');
}

Events Manager Validation

  1. Navigate to Reddit Ads Manager > Events Manager
  2. Select your pixel
  3. Click "Test Events"
  4. Open your website with test code active
  5. Trigger events and verify they appear in test view
  6. Check event parameters are correct

Best Practices

Event Naming

  • Use standard events whenever possible for better optimization
  • Keep custom event names descriptive and consistent
  • Use PascalCase for custom event names: StartFreeTrial, VideoWatched
  • Avoid special characters in event names

Parameter Standards

  • Always include value and currency for monetary events
  • Use decimal values for currency: 99.99 not 9999
  • Include transactionId for purchase events (deduplication)
  • Keep parameter names consistent across events

Performance

  • Fire events after user action completes (form submission, payment confirmation)
  • Don't fire events on page load unless appropriate (PageView only)
  • Use debouncing for high-frequency events (scroll, search input)
  • Avoid blocking page load with event tracking

Data Quality

  • Validate parameter values before sending (check for null, undefined, NaN)
  • Use proper data types (numbers for value, strings for transactionId)
  • Test events in Events Manager before production deployment
  • Monitor event counts in Events Manager after deployment

Privacy Compliance

  • Hash PII (email, phone) using SHA-256 before sending
  • Respect user consent preferences before firing pixel
  • Include pixel usage in privacy policy
  • Honor opt-out requests via consent management

Troubleshooting

  • Use browser console to verify pixel loaded: typeof rdt
  • Check Network tab for requests to redditstatic.com and alb.reddit.com
  • Verify events appear in Events Manager within 30 minutes
  • Test in multiple browsers (Chrome, Firefox, Safari)
  • Review Events Manager diagnostics for errors