Meta Pixel Event Tracking on Sitecore | Blue Frog Docs

Meta Pixel Event Tracking on Sitecore

Implement Meta Pixel custom event tracking for conversions, lead generation, and remarketing on Sitecore

Meta Pixel Event Tracking on Sitecore

Learn how to track custom events with Meta Pixel on Sitecore websites for conversion optimization, lead generation, and retargeting campaigns.

Prerequisites

Standard Events

Meta provides standard events for common actions. Use these when possible for better optimization.

Standard Event List

  • Purchase - Completed purchase
  • Lead - Lead generated (form submission)
  • CompleteRegistration - Registration completed
  • AddToCart - Product added to cart
  • InitiateCheckout - Checkout initiated
  • AddPaymentInfo - Payment info added
  • Contact - Contact information submitted
  • ViewContent - Content viewed (product, article)
  • Search - Search performed
  • AddToWishlist - Product added to wishlist

Basic Event Tracking

Track Button Clicks

@* Button with Meta Pixel tracking *@
<button onclick="fbq('track', 'Contact', {
    'content_name': 'Contact Form',
    'content_category': '@Sitecore.Context.Item.TemplateName'
});">
    Contact Us
</button>
@* Track outbound or important link clicks *@
<a href="@Model.Item["Link"]"
   onclick="fbq('track', 'ViewContent', {
       'content_type': 'link',
       'content_name': '@Model.Item["Link Text"]'
   });">
    @Model.Item["Link Text"]
</a>

Sitecore Forms Event Tracking

Track Form Submissions

Method 1: Custom Submit Action

// /Forms/SubmitActions/MetaPixelSubmitAction.cs
using Sitecore.Diagnostics;
using Sitecore.ExperienceForms.Models;
using Sitecore.ExperienceForms.Processing;
using Sitecore.ExperienceForms.Processing.Actions;

namespace YourProject.Forms.SubmitActions
{
    public class MetaPixelSubmitAction : SubmitActionBase<string>
    {
        public MetaPixelSubmitAction(ISubmitActionData submitActionData)
            : base(submitActionData)
        {
        }

        protected override bool Execute(string data, FormSubmitContext formSubmitContext)
        {
            Assert.ArgumentNotNull(formSubmitContext, nameof(formSubmitContext));

            var formName = formSubmitContext.FormName;

            // Store form submission for client-side tracking
            formSubmitContext.Items["MetaPixelEvent"] = new
            {
                eventName = "Lead",
                eventParams = new
                {
                    content_name = formName,
                    content_category = "Form Submission",
                    value = 0
                }
            };

            return true;
        }
    }
}

Method 2: Client-Side Form Tracking

// /scripts/analytics/meta-pixel-forms.js
document.addEventListener('DOMContentLoaded', function() {
    // Track Sitecore Forms
    var sitecoreForms = document.querySelectorAll('form[data-sc-fxb-form]');

    sitecoreForms.forEach(function(form) {
        var formName = form.getAttribute('data-sc-fxb-form') || 'Unknown Form';

        // Track form submission
        form.addEventListener('submit', function(e) {
            fbq('track', 'Lead', {
                'content_name': formName,
                'content_category': 'Form',
                'value': 0,
                'currency': 'USD'
            });
        });

        // Track form start
        var formStarted = false;
        form.querySelectorAll('input, textarea, select').forEach(function(input) {
            input.addEventListener('focus', function() {
                if (!formStarted) {
                    formStarted = true;

                    fbq('trackCustom', 'FormStart', {
                        'content_name': formName
                    });
                }
            }, { once: true });
        });
    });
});

E-commerce Event Tracking

ViewContent Event (Product Page)

@* Product detail page *@
@{
    var product = Model.Item; // Your product item
    var productId = product["Product ID"];
    var productName = product.DisplayName;
    var productPrice = product["Price"];
    var productCategory = product["Category"];
}

<script>
    fbq('track', 'ViewContent', {
        'content_ids': ['@productId'],
        'content_type': 'product',
        'content_name': '@productName',
        'content_category': '@productCategory',
        'value': @productPrice,
        'currency': 'USD'
    });
</script>

AddToCart Event

// /scripts/commerce/meta-pixel-ecommerce.js
function addToCart(productId, productName, price, quantity) {
    // Call Sitecore Commerce API
    fetch('/api/commerce/cart/add', {
        method: 'POST',
        headers: {
            'Content-Type': 'application/json'
        },
        body: JSON.stringify({
            productId: productId,
            quantity: quantity
        })
    })
    .then(response => response.json())
    .then(data => {
        if (data.success) {
            // Track add to cart
            fbq('track', 'AddToCart', {
                'content_ids': [productId],
                'content_name': productName,
                'content_type': 'product',
                'value': price * quantity,
                'currency': 'USD'
            });

            // Update UI
            updateCartCount(data.cartItemCount);
        }
    });
}

InitiateCheckout Event

@* Checkout page *@
@model CommerceCart

@if (Model != null && Model.Lines.Any())
{
    <script>
        fbq('track', 'InitiateCheckout', {
            'content_ids': [@Html.Raw(string.Join(",", Model.Lines.Select(l => $"'{l.Product.ProductId}'")))],
            'content_type': 'product',
            'num_items': @Model.Lines.Count,
            'value': @Model.Total.Amount,
            'currency': '@Model.Total.CurrencyCode'
        });
    </script>
}

Purchase Event

@* Order confirmation page *@
@model CommerceOrder

<script>
    fbq('track', 'Purchase', {
        'content_ids': [@Html.Raw(string.Join(",", Model.Lines.Select(l => $"'{l.Product.ProductId}'")))],
        'content_type': 'product',
        'contents': [
            @foreach (var line in Model.Lines)
            {
                <text>
                {
                    'id': '@line.Product.ProductId',
                    'quantity': @line.Quantity,
                    'item_price': @line.Product.Price.Amount
                },
                </text>
            }
        ],
        'value': @Model.Total.Amount,
        'currency': '@Model.Total.CurrencyCode',
        'num_items': @Model.Lines.Count
    });
</script>

Lead Generation Events

CompleteRegistration

@* User registration confirmation *@
<script>
    fbq('track', 'CompleteRegistration', {
        'content_name': 'User Registration',
        'status': 'completed',
        'value': 0,
        'currency': 'USD'
    });
</script>

Contact Event

// Track contact form submission
function submitContactForm() {
    fbq('track', 'Contact', {
        'content_name': 'Contact Form',
        'content_category': 'Lead Generation'
    });
}

Subscribe Event

// Track newsletter subscription
function subscribeNewsletter(email) {
    fbq('track', 'Subscribe', {
        'predicted_ltv': 0,
        'value': 0,
        'currency': 'USD'
    });
}

Custom Events

For actions not covered by standard events, use custom events:

// Custom event for resource download
function trackDownload(fileName) {
    fbq('trackCustom', 'ResourceDownload', {
        'resource_name': fileName,
        'resource_type': fileName.split('.').pop()
    });
}

// Custom event for video play
function trackVideoPlay(videoName) {
    fbq('trackCustom', 'VideoPlay', {
        'video_name': videoName
    });
}

// Custom event for chat interaction
function trackChatStart() {
    fbq('trackCustom', 'ChatStart', {
        'page_url': window.location.pathname
    });
}

Server-Side Event Tracking with Conversions API

For more reliable tracking, implement server-side events:

// /Services/MetaConversionsApiService.cs
using System;
using System.Collections.Generic;
using System.Net.Http;
using System.Text;
using Newtonsoft.Json;

namespace YourProject.Services
{
    public class MetaConversionsApiService
    {
        private readonly string _pixelId;
        private readonly string _accessToken;
        private readonly HttpClient _httpClient;

        public MetaConversionsApiService(string pixelId, string accessToken)
        {
            _pixelId = pixelId;
            _accessToken = accessToken;
            _httpClient = new HttpClient();
        }

        public async Task<bool> TrackEventAsync(string eventName, Dictionary<string, object> customData,
            string userIpAddress, string userAgent, string fbp = null, string fbc = null)
        {
            try
            {
                var eventData = new
                {
                    data = new[]
                    {
                        new
                        {
                            event_name = eventName,
                            event_time = DateTimeOffset.UtcNow.ToUnixTimeSeconds(),
                            action_source = "website",
                            user_data = new
                            {
                                client_ip_address = userIpAddress,
                                client_user_agent = userAgent,
                                fbp = fbp,
                                fbc = fbc
                            },
                            custom_data = customData
                        }
                    }
                };

                var json = JsonConvert.SerializeObject(eventData);
                var content = new StringContent(json, Encoding.UTF8, "application/json");

                var url = $"https://graph.facebook.com/v18.0/{_pixelId}/events?access_token={_accessToken}";
                var response = await _httpClient.PostAsync(url, content);

                return response.IsSuccessStatusCode;
            }
            catch (Exception ex)
            {
                Sitecore.Diagnostics.Log.Error($"Meta Conversions API error: {ex.Message}", this);
                return false;
            }
        }
    }
}

Use in Controller:

// /Controllers/CheckoutController.cs
[HttpPost]
public async Task<ActionResult> CompleteOrder(OrderModel orderModel)
{
    var order = SubmitOrder(orderModel);

    if (order != null)
    {
        // Track server-side
        var metaService = new MetaConversionsApiService(
            ConfigurationManager.AppSettings["MetaPixel.Id"],
            ConfigurationManager.AppSettings["MetaPixel.AccessToken"]
        );

        var customData = new Dictionary<string, object>
        {
            ["value"] = order.Total.Amount,
            ["currency"] = order.Total.CurrencyCode,
            ["content_ids"] = order.Lines.Select(l => l.Product.ProductId).ToArray(),
            ["content_type"] = "product"
        };

        var userIp = Request.UserHostAddress;
        var userAgent = Request.UserAgent;
        var fbp = Request.Cookies["_fbp"]?.Value;
        var fbc = Request.Cookies["_fbc"]?.Value;

        await metaService.TrackEventAsync("Purchase", customData, userIp, userAgent, fbp, fbc);

        return View("OrderConfirmation", order);
    }

    return View("Error");
}

Deduplication with Event ID

Prevent duplicate events when using both browser pixel and Conversions API:

Browser Pixel:

var eventId = 'order_' + orderId + '_' + Date.now();

fbq('track', 'Purchase', {
    'value': orderTotal,
    'currency': 'USD'
}, {
    'eventID': eventId
});

// Send eventId to server for Conversions API

Server-Side:

var eventData = new
{
    data = new[]
    {
        new
        {
            event_name = "Purchase",
            event_id = eventId, // Same ID from browser
            // ... rest of event data
        }
    }
};

Dynamic Event Parameters with Sitecore Context

@using Sitecore.Analytics

@{
    var pageTemplate = Sitecore.Context.Item.TemplateName;
    var language = Sitecore.Context.Language.Name;

    // Get visitor data from xDB
    string visitorSegment = "unknown";
    if (Tracker.Current != null && Tracker.Current.IsActive)
    {
        var contact = Tracker.Current.Contact;
        visitorSegment = contact?.System.VisitCount > 3 ? "returning" : "new";
    }
}

<script>
    fbq('track', 'PageView', {
        'page_template': '@pageTemplate',
        'page_language': '@language',
        'visitor_segment': '@visitorSegment'
    });
</script>

Integration with GTM

Track Meta Pixel events via Google Tag Manager data layer:

// Push to dataLayer, let GTM handle Meta Pixel
window.dataLayer.push({
    'event': 'addToCart',
    'ecommerce': {
        'value': productPrice,
        'items': [{
            'item_id': productId,
            'item_name': productName
        }]
    }
});

In GTM, create trigger on 'addToCart' event and fire Meta Pixel tag.

Tracking with SXA Components

@* SXA component tracking *@
@using Sitecore.XA.Foundation.Mvc.Extensions

@{
    var componentName = Model.RenderingItem.Name;
}

<div class="cta-component">
    <a href="@Model.Item["Link"]"
       onclick="fbq('trackCustom', 'SXAComponentClick', {
           'component_name': '@componentName',
           'component_type': '@Model.RenderingItem.TemplateName'
       });">
        @Model.Item["Call to Action Text"]
    </a>
</div>

JSS/Headless Event Tracking

Next.js Implementation

// /src/lib/metaPixel.ts
export const trackEvent = (eventName: string, params?: Record<string, any>) => {
  if (typeof window !== 'undefined' && window.fbq) {
    window.fbq('track', eventName, params);
  }
};

export const trackCustomEvent = (eventName: string, params?: Record<string, any>) => {
  if (typeof window !== 'undefined' && window.fbq) {
    window.fbq('trackCustom', eventName, params);
  }
};

export const trackPurchase = (value: number, currency: string, contentIds: string[]) => {
  trackEvent('Purchase', {
    value,
    currency,
    content_ids: contentIds,
    content_type: 'product',
  });
};

Use in Component:

// /src/components/Product/AddToCart.tsx
import { trackEvent } from '@/lib/metaPixel';

const AddToCart = ({ product }: AddToCartProps) => {
  const handleAddToCart = () => {
    trackEvent('AddToCart', {
      content_ids: [product.id],
      content_name: product.name,
      content_type: 'product',
      value: product.price,
      currency: 'USD',
    });

    // Add to cart logic
  };

  return <button onClick={handleAddToCart}>Add to Cart</button>;
};

Only fire events after consent:

function checkConsent() {
    return localStorage.getItem('cookieConsent') === 'true';
}

function trackEventWithConsent(eventName, params) {
    if (checkConsent() && typeof fbq === 'function') {
        fbq('track', eventName, params);
    }
}

// Usage
trackEventWithConsent('AddToCart', {
    'value': 29.99,
    'currency': 'USD'
});

Debugging Events

Meta Pixel Helper

Install Meta Pixel Helper:

  • Shows all events firing
  • Displays event parameters
  • Highlights errors

Browser Console

// Check if fbq is available
console.log(typeof fbq);

// Log all Meta Pixel events
window._fbq_debugEnabled = true;

// Track custom event with console log
function trackWithLog(eventName, params) {
    console.log('Meta Pixel Event:', eventName, params);
    fbq('track', eventName, params);
}

Test Events

Use Test Events in Events Manager:

  1. Add test event code to pixel initialization
  2. Trigger events on site
  3. Check Events Manager > Test Events tab
<script>
    fbq('init', 'YOUR_PIXEL_ID');
    fbq('track', 'PageView', {}, {'eventID': 'test_event_12345'});
</script>

Best Practices

1. Use Standard Events When Possible

Standard events are optimized for Facebook's algorithm.

2. Include Value and Currency

Always include value and currency for conversion events:

fbq('track', 'Lead', {
    'value': 0,
    'currency': 'USD'
});

3. Use Event Deduplication

Use event IDs to prevent duplicate tracking.

4. Implement Conversions API

Server-side tracking is more reliable than browser-only tracking.

5. Don't Track PII

Avoid sending personally identifiable information in event parameters.

Common Issues

Issue: Events Not Showing in Events Manager

Causes:

  • Pixel not properly initialized
  • Ad blockers preventing tracking
  • Events Manager delay (can take 20 minutes)

Solutions:

  • Check Meta Pixel Helper
  • Test in incognito mode
  • Wait for Events Manager to update

Issue: Duplicate Events

Cause: Event fired multiple times

Solution: Use event IDs or track only once per action

Next Steps

// SYS.FOOTER