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
- Meta Pixel installed on Sitecore
- Basic understanding of Meta Pixel events
- Access to modify Sitecore views and JavaScript
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 Link Clicks
@* 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>;
};
Consent Management
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:
- Add test event code to pixel initialization
- Trigger events on site
- 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