Meta Pixel Event Tracking on Kentico | OpsBlu Docs

Meta Pixel Event Tracking on Kentico

Implement custom event tracking for Facebook Pixel (Meta Pixel) on Kentico Xperience websites

Learn how to implement custom event tracking for Meta Pixel on Kentico Xperience, including standard events, custom events, and e-commerce tracking.

Prerequisites

Standard Events Overview

Meta provides standard events for common actions:

Event Use Case
ViewContent Product/content page views
Search Search actions
AddToCart Adding items to cart
AddToWishlist Adding to wishlist
InitiateCheckout Starting checkout
AddPaymentInfo Adding payment info
Purchase Completed purchase
Lead Lead generation (form submission)
CompleteRegistration User registration
Contact Contact form submission
Subscribe Newsletter/subscription

Standard Event Implementation

ViewContent Event

Track product or content page views:

@using CMS.DocumentEngine
@using CMS.Ecommerce
@{
    var currentDoc = DocumentContext.CurrentDocument;
}

@if (currentDoc.ClassName == "Custom.Product")
{
    var product = (SKUInfo)currentDoc.GetValue("ProductSKU");

    <script>
      fbq('track', 'ViewContent', {
        content_name: '@currentDoc.DocumentName',
        content_category: '@currentDoc.GetValue("Category")',
        content_ids: ['@product.SKUNumber'],
        content_type: 'product',
        value: @product.SKUPrice,
        currency: '@CurrencyInfoProvider.GetMainCurrency(SiteContext.CurrentSiteID).CurrencyCode'
      });
    </script>
}

For Kentico E-commerce products:

@using CMS.Ecommerce
@model SKUInfo

<script>
  fbq('track', 'ViewContent', {
    content_name: '@Model.SKUName',
    content_category: '@(Model.PrimaryCategory?.CategoryDisplayName ?? "")',
    content_ids: ['@Model.SKUNumber'],
    content_type: 'product',
    value: @Model.SKUPrice,
    currency: '@CurrencyInfoProvider.GetMainCurrency(SiteContext.CurrentSiteID).CurrencyCode'
  });
</script>

Search Event

Track site searches:

@if (!string.IsNullOrEmpty(ViewBag.SearchQuery))
{
    <script>
      fbq('track', 'Search', {
        search_string: '@ViewBag.SearchQuery',
        content_category: '@ViewBag.SearchCategory',
        content_ids: [@Html.Raw(string.Join(",", ViewBag.ResultIds.Select(id => $"'{id}'"))))]
      });
    </script>
}

AddToCart Event

Track when users add products to cart:

Client-Side (AJAX)

<script>
  function addToCart(productId) {
    // AJAX call to add product
    $.ajax({
      url: '/ShoppingCart/AddItem',
      method: 'POST',
      data: { skuId: productId, quantity: 1 },
      success: function(response) {
        // Track add to cart
        fbq('track', 'AddToCart', {
          content_name: response.product.name,
          content_ids: [response.product.skuNumber],
          content_type: 'product',
          value: response.product.price,
          currency: response.currency
        });

        // Update cart UI
        updateCartDisplay(response);
      }
    });
  }
</script>

<button to Cart</button>

Server-Side (Traditional Form Post)

In your controller:

using CMS.Ecommerce;
using Newtonsoft.Json;

public ActionResult AddToCart(int skuId, int quantity)
{
    var sku = SKUInfoProvider.GetSKUInfo(skuId);
    var cart = ECommerceContext.CurrentShoppingCart;

    cart.AddItem(skuId, quantity);
    cart.Evaluate();

    // Prepare tracking data
    ViewBag.AddToCartEvent = new
    {
        content_name = sku.SKUName,
        content_ids = new[] { sku.SKUNumber },
        content_type = "product",
        value = sku.SKUPrice * quantity,
        currency = cart.Currency.CurrencyCode
    };

    return View("Cart");
}

In your view:

@if (ViewBag.AddToCartEvent != null)
{
    <script>
      fbq('track', 'AddToCart', @Html.Raw(Json.Encode(ViewBag.AddToCartEvent)));
    </script>
}

InitiateCheckout Event

Track when users begin checkout:

@using CMS.Ecommerce
@{
    var cart = ECommerceContext.CurrentShoppingCart;
    var contentIds = cart.CartItems.Select(item => item.SKU.SKUNumber).ToArray();
}

<script>
  fbq('track', 'InitiateCheckout', {
    content_category: 'checkout',
    content_ids: [@Html.Raw(string.Join(",", contentIds.Select(id => $"'{id}'")))],
    num_items: @cart.CartItems.Count,
    value: @cart.TotalPrice,
    currency: '@cart.Currency.CurrencyCode'
  });
</script>

AddPaymentInfo Event

Track payment method selection:

<script>
  function selectPaymentMethod(methodName) {
    fbq('track', 'AddPaymentInfo', {
      content_category: 'checkout',
      value: @cart.TotalPrice,
      currency: '@cart.Currency.CurrencyCode'
    });

    // Submit payment method
    submitPaymentSelection(methodName);
  }
</script>

<button Card</button>
<button

Purchase Event (Critical!)

Track completed transactions:

@using CMS.Ecommerce
@model OrderInfo

<script>
  fbq('track', 'Purchase', {
    value: @Model.OrderGrandTotal,
    currency: '@Model.OrderCurrency.CurrencyCode',
    content_ids: [@Html.Raw(string.Join(",", Model.OrderItems.Select(item => $"'{item.OrderItemSKU.SKUNumber}'")))],
    content_type: 'product',
    num_items: @Model.OrderItems.Sum(item => item.OrderItemUnitCount)
  });
</script>

<h1>Thank You for Your Order!</h1>
<p>Order #@Model.OrderID</p>

Prevent Duplicate Purchase Tracking

@{
    var purchaseTracked = SessionHelper.GetValue("MetaPixel_Purchase_" + Model.OrderID);
}

@if (purchaseTracked == null)
{
    SessionHelper.SetValue("MetaPixel_Purchase_" + Model.OrderID, true);

    <script>
      fbq('track', 'Purchase', {
        value: @Model.OrderGrandTotal,
        currency: '@Model.OrderCurrency.CurrencyCode',
        content_ids: [@Html.Raw(string.Join(",", Model.OrderItems.Select(item => $"'{item.OrderItemSKU.SKUNumber}'")))],
        content_type: 'product'
      });
    </script>
}

Lead Event

Track lead generation (form submissions):

@if (ViewBag.FormSubmitted == true)
{
    <script>
      fbq('track', 'Lead', {
        content_name: '@ViewBag.FormName',
        content_category: 'lead_generation',
        value: @ViewBag.LeadValue,
        currency: 'USD'
      });
    </script>
}

Or with client-side tracking:

<script>
  document.getElementById('leadForm').addEventListener('submit', function(e) {
    fbq('track', 'Lead', {
      content_name: 'contact_form',
      content_category: 'lead_generation'
    });
  });
</script>

CompleteRegistration Event

Track user registrations:

@if (ViewBag.RegistrationComplete == true)
{
    <script>
      fbq('track', 'CompleteRegistration', {
        content_name: 'user_registration',
        status: 'completed',
        value: 0,
        currency: 'USD'
      });
    </script>
}

Contact Event

Track contact form submissions:

<script>
  document.getElementById('contactForm').addEventListener('submit', function(e) {
    fbq('track', 'Contact', {
      content_name: 'contact_form',
      content_category: 'customer_support'
    });
  });
</script>

Subscribe Event

Track newsletter signups:

<script>
  document.getElementById('newsletterForm').addEventListener('submit', function(e) {
    fbq('track', 'Subscribe', {
      value: 0,
      currency: 'USD',
      predicted_ltv: 100
    });
  });
</script>

Custom Events

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

<script>
  // Track custom event
  fbq('trackCustom', 'EventName', {
    customParam1: 'value1',
    customParam2: 'value2'
  });
</script>

Example: Product Comparison

<script>
  function trackProductComparison(productIds) {
    fbq('trackCustom', 'CompareProducts', {
      product_ids: productIds,
      num_products: productIds.length
    });
  }

  // Usage
  trackProductComparison(['SKU123', 'SKU456', 'SKU789']);
</script>

Example: Video View

<script>
  var video = document.getElementById('productVideo');

  video.addEventListener('play', function() {
    fbq('trackCustom', 'VideoView', {
      video_title: this.getAttribute('data-title'),
      product_id: '@Model.SKUNumber'
    });
  });
</script>

Example: Download Brochure

<script>
  document.querySelectorAll('.brochure-download').forEach(function(link) {
    link.addEventListener('click', function(e) {
      fbq('trackCustom', 'DownloadBrochure', {
        brochure_name: this.getAttribute('data-brochure-name'),
        product_category: this.getAttribute('data-category')
      });
    });
  });
</script>

Advanced E-commerce Tracking

Product Catalog Events

Track product listing page views:

@model IEnumerable<SKUInfo>

<script>
  fbq('track', 'ViewContent', {
    content_type: 'product_group',
    content_category: '@ViewBag.CategoryName',
    content_ids: [@Html.Raw(string.Join(",", Model.Select(p => $"'{p.SKUNumber}'")))],
    contents: [
      @foreach (var product in Model)
      {
        @:{
          id: '@product.SKUNumber',
          quantity: 1,
          item_price: @product.SKUPrice
        }@(product != Model.Last() ? "," : "")
      }
    ]
  });
</script>

Dynamic Product Ads (DPA) Format

For dynamic remarketing:

@model SKUInfo

<script>
  fbq('track', 'ViewContent', {
    content_type: 'product',
    content_ids: ['@Model.SKUNumber'],
    content_name: '@Model.SKUName',
    content_category: '@(Model.PrimaryCategory?.CategoryDisplayName ?? "")',
    value: @Model.SKUPrice,
    currency: '@CurrencyInfoProvider.GetMainCurrency(SiteContext.CurrentSiteID).CurrencyCode',
    contents: [{
      id: '@Model.SKUNumber',
      quantity: 1,
      item_price: @Model.SKUPrice
    }]
  });
</script>

Remove from Cart

<script>
  function removeFromCart(cartItemId, itemData) {
    $.ajax({
      url: '/ShoppingCart/RemoveItem',
      method: 'POST',
      data: { cartItemId: cartItemId },
      success: function(response) {
        fbq('trackCustom', 'RemoveFromCart', {
          content_ids: [itemData.skuNumber],
          content_name: itemData.skuName,
          value: itemData.price * itemData.quantity,
          currency: itemData.currency
        });
      }
    });
  }
</script>

Event Parameters Reference

Common Parameters

Parameter Type Description
value number Monetary value of event
currency string Currency code (USD, EUR, etc.)
content_name string Name of content/product
content_category string Category of content
content_ids array Product/content IDs
content_type string Type: product, product_group
contents array Detailed product info
num_items number Number of items

E-commerce Specific

Parameter Type Description
contents array Array of product objects
predicted_ltv number Predicted lifetime value
status string Status of action

Kentico-Specific Integrations

Track Page Type Views

@using CMS.DocumentEngine
@{
    var currentDoc = DocumentContext.CurrentDocument;
}

<script>
  fbq('trackCustom', 'PageTypeView', {
    page_type: '@currentDoc.ClassName',
    page_name: '@currentDoc.DocumentName',
    page_id: '@currentDoc.DocumentID'
  });
</script>

Track Content Downloads

@using CMS.MediaLibrary

<script>
  document.querySelectorAll('.media-download').forEach(function(link) {
    link.addEventListener('click', function(e) {
      fbq('trackCustom', 'DownloadContent', {
        content_name: this.getAttribute('data-file-name'),
        content_type: this.getAttribute('data-file-type'),
        source: 'media_library'
      });
    });
  });
</script>

Track Form Builder Forms

@using CMS.OnlineForms

<script>
  document.querySelectorAll('form[data-kentico-form]').forEach(function(form) {
    form.addEventListener('submit', function(e) {
      var formName = this.getAttribute('data-kentico-form');

      fbq('track', 'Lead', {
        content_name: formName,
        content_category: 'kentico_form',
        value: 0,
        currency: 'USD'
      });
    });
  });
</script>

GTM Implementation (Alternative)

If using Google Tag Manager:

Create Meta Pixel Event Tag

  1. In GTM, create new tag
  2. Tag Configuration: Custom HTML
  3. HTML:
<script>
  fbq('track', '{{Event Name}}', {
    value: {{Event Value}},
    currency: '{{Currency}}',
    content_ids: [{{Content IDs}}]
  });
</script>
  1. Set up Variables:

    • Event Name (Data Layer Variable)
    • Event Value (Data Layer Variable)
    • Currency (Data Layer Variable)
    • Content IDs (Data Layer Variable)
  2. Trigger: Custom Event from data layer

Data Layer Push in Kentico

<script>
  window.dataLayer = window.dataLayer || [];
  window.dataLayer.push({
    'event': 'addToCart',
    'ecommerce': {
      'currencyCode': '@cart.Currency.CurrencyCode',
      'add': {
        'products': [{
          'id': '@product.SKUNumber',
          'name': '@product.SKUName',
          'price': @product.SKUPrice,
          'quantity': 1
        }]
      }
    },
    'fbPixelValue': @product.SKUPrice,
    'fbPixelContentIds': ['@product.SKUNumber']
  });
</script>

Testing Events

1. Meta Pixel Helper

  • Install Chrome extension
  • Navigate to your site
  • Perform actions
  • Check helper icon for events
  • Verify parameters are correct

2. Facebook Events Manager

  1. Open Events Manager
  2. Click Test Events
  3. Enter your website URL
  4. Perform actions on site
  5. Watch events appear in real-time
  6. Verify parameters

3. Browser Console Logging

<script>
  // Log all Meta Pixel events
  (function() {
    var originalFbq = window.fbq;
    window.fbq = function() {
      console.log('Meta Pixel Event:', arguments);
      return originalFbq.apply(this, arguments);
    };
  })();
</script>

4. Network Tab Inspection

  • Open DevTools → Network
  • Filter by "facebook"
  • Perform action
  • Check for request to facebook.com/tr
  • Verify event parameters in request

Event Deduplication

To prevent duplicate events across different tracking methods:

<script>
  fbq('track', 'Purchase', {
    value: @Model.OrderGrandTotal,
    currency: '@Model.OrderCurrency.CurrencyCode',
    content_ids: ['@Model.OrderID']
  }, {
    eventID: 'purchase_@Model.OrderID'
  });
</script>

Use same eventID in Conversions API to deduplicate.

Common Issues

Events Not Tracking

Check:

  • Meta Pixel base code loaded before event code
  • Correct event name (case-sensitive)
  • JavaScript errors in console
  • Network requests in DevTools

Wrong Event Parameters

Debug:

  • Use Meta Pixel Helper
  • Check Events Manager for parameter values
  • Verify data types (numbers vs strings)
  • Ensure required parameters are included

Currency Issues

Fix:

@{
    // Always use ISO 4217 currency codes
    var currency = CurrencyInfoProvider.GetMainCurrency(SiteContext.CurrentSiteID).CurrencyCode;
}

<script>
  fbq('track', 'Purchase', {
    value: @Model.OrderGrandTotal,
    currency: '@currency'  // e.g., 'USD', 'EUR', 'GBP'
  });
</script>

Best Practices

  1. Use Standard Events: Prefer standard events over custom for better optimization
  2. Include Value: Always include monetary value when applicable
  3. Product IDs: Use consistent SKU numbers as content_ids
  4. Test Thoroughly: Test all events before launching campaigns
  5. Deduplicate: Use eventID to prevent duplicate counting
  6. Privacy Compliance: Don't send PII in event parameters
  7. Consistent Currency: Use same currency across all events
  8. Monitor Regularly: Check Events Manager for data quality

Event Value Assignment

Assign values to non-purchase events for optimization:

<script>
  // Lead form with estimated value
  fbq('track', 'Lead', {
    content_name: 'demo_request',
    value: 50.00,  // Estimated lead value
    currency: 'USD',
    predicted_ltv: 500.00  // Predicted lifetime value
  });
</script>

Next Steps

Additional Resources