BigCommerce Meta Pixel Event Tracking
Track the complete customer journey on your BigCommerce store using Meta Pixel standard events and custom events. This guide covers ecommerce tracking and user interactions specific to BigCommerce.
Meta Pixel Standard Events
Meta provides predefined standard events optimized for ecommerce tracking and ad optimization.
Ecommerce Standard Events
| Event | Description | When to Fire |
|---|---|---|
ViewContent |
User views product page | Product page load |
Search |
User performs search | Search results page |
AddToCart |
Product added to cart | Add to cart button click |
AddToWishlist |
Product added to wishlist | Wishlist button click |
InitiateCheckout |
User starts checkout | Checkout page load |
AddPaymentInfo |
Payment method entered | Payment step in checkout |
Purchase |
Transaction completed | Order confirmation page |
Engagement Standard Events
| Event | Description | When to Fire |
|---|---|---|
Lead |
Newsletter signup, form submit | Form submission |
CompleteRegistration |
Account created | Registration success |
Contact |
Contact form submitted | Contact form submit |
Implementation Methods
Method 1: Stencil Theme Integration (Recommended)
Full access to BigCommerce context data for accurate event tracking.
Track ViewContent on Product Pages
File: templates/pages/product.html
{{#with product}}
<script>
(function() {
if (typeof fbq === 'undefined') return;
// Track product view
fbq('track', 'ViewContent', {
content_ids: ['{{id}}'],
content_name: '{{title}}',
content_type: 'product',
value: {{price.without_tax.value}},
currency: '{{../currency.code}}',
content_category: '{{category.[0]}}',
// Enhanced parameters
availability: '{{availability}}',
condition: '{{condition}}',
brand: '{{brand.name}}'
});
})();
</script>
{{/with}}
Track Search Events
File: templates/pages/search.html
<script>
(function() {
if (typeof fbq === 'undefined') return;
var searchQuery = '{{sanitize forms.search.query}}';
var resultsCount = {{products.length}};
fbq('track', 'Search', {
search_string: searchQuery,
content_category: 'product_search',
// Additional context
results_count: resultsCount,
has_results: resultsCount > 0
});
})();
</script>
Track AddToCart Events
File: assets/js/theme/common/cart-item-details.js
export function trackAddToCart(productId, quantity = 1) {
// Fetch full product details from Storefront API
fetch(`/api/storefront/products/${productId}`)
.then(response => response.json())
.then(product => {
if (typeof fbq !== 'undefined') {
fbq('track', 'AddToCart', {
content_ids: [product.id.toString()],
content_name: product.name,
content_type: 'product',
value: product.price.without_tax.value * quantity,
currency: product.currency || 'USD',
contents: [{
id: product.id.toString(),
quantity: quantity,
item_price: product.price.without_tax.value
}]
});
}
})
.catch(error => console.error('Error tracking AddToCart:', error));
}
// Hook into BigCommerce cart event
import $ from 'jquery';
$('body').on('cart-item-add', (event, productId, quantity) => {
trackAddToCart(productId, quantity);
});
Track AddToWishlist
File: assets/js/theme/global/wishlist.js or add to product page
document.addEventListener('click', function(e) {
const wishlistButton = e.target.closest('[data-wishlist-add]');
if (wishlistButton) {
const productId = wishlistButton.getAttribute('data-product-id');
const productName = wishlistButton.getAttribute('data-product-name');
const productPrice = wishlistButton.getAttribute('data-product-price');
if (typeof fbq !== 'undefined') {
fbq('track', 'AddToWishlist', {
content_ids: [productId],
content_name: productName,
content_type: 'product',
value: parseFloat(productPrice) || 0,
currency: 'USD' // Or pull from context
});
}
}
});
Track InitiateCheckout
Location: Settings > Checkout > Header Scripts (Plus, Pro, Enterprise plans)
<script>
(function() {
// Only fire on checkout, not confirmation
if (!window.location.pathname.includes('order-confirmation')) {
// Poll for BigCommerce checkout data
var checkoutInterval = setInterval(function() {
if (typeof BCData !== 'undefined' && BCData.checkout) {
clearInterval(checkoutInterval);
var checkout = BCData.checkout;
var items = checkout.cart.lineItems.physicalItems;
// Calculate total value
var totalValue = items.reduce(function(sum, item) {
return sum + (item.salePrice * item.quantity);
}, 0);
// Get all product IDs
var productIds = items.map(function(item) {
return item.productId.toString();
});
// Track checkout initiation
if (typeof fbq !== 'undefined') {
fbq('track', 'InitiateCheckout', {
content_ids: productIds,
content_type: 'product',
value: totalValue,
currency: checkout.cart.currency.code,
num_items: items.length,
contents: items.map(function(item) {
return {
id: item.productId.toString(),
quantity: item.quantity,
item_price: item.salePrice
};
})
});
}
}
}, 100);
// Stop checking after 10 seconds
setTimeout(function() {
clearInterval(checkoutInterval);
}, 10000);
}
})();
</script>
Track Purchase
File: templates/pages/order-confirmation.html
{{#if order}}
<script>
(function() {
if (typeof fbq === 'undefined') return;
// Build product array
var productIds = [
{{#each order.items}}
'{{product_id}}'{{#unless @last}},{{/unless}}
{{/each}}
];
var contents = [
{{#each order.items}}
{
id: '{{product_id}}',
quantity: {{quantity}},
item_price: {{price}}
}{{#unless @last}},{{/unless}}
{{/each}}
];
// Track purchase
fbq('track', 'Purchase', {
content_ids: productIds,
content_type: 'product',
value: {{order.total}},
currency: '{{order.currency.code}}',
num_items: {{order.items.length}},
contents: contents,
// Additional transaction data
transaction_id: '{{order.id}}',
{{#if order.coupon_code}}
coupon_code: '{{order.coupon_code}}',
{{/if}}
tax: {{order.tax_total}},
shipping: {{order.shipping_cost}}
});
})();
</script>
{{/if}}
Alternative: Conversion Tracking Script (All Plans)
In Settings > Analytics > Conversion Tracking Code:
<script>
if (typeof fbq !== 'undefined') {
fbq('track', 'Purchase', {
value: %%ORDER_AMOUNT%%,
currency: '%%GLOBAL_CurrencyCode%%',
content_type: 'product',
transaction_id: '%%ORDER_ID%%'
});
}
</script>
Method 2: Script Manager Implementation (Limited)
For stores without Stencil access, implement basic event tracking via Script Manager.
Track AddToCart via Script Manager
<script>
(function() {
document.addEventListener('DOMContentLoaded', function() {
document.addEventListener('click', function(e) {
const addToCartBtn = e.target.closest('[data-button-type="add-cart"]') ||
e.target.closest('.button--add-to-cart');
if (addToCartBtn && typeof fbq !== 'undefined') {
// Limited data without Stencil context
const productCard = addToCartBtn.closest('[data-product-id]');
const productId = productCard?.getAttribute('data-product-id');
if (productId) {
fbq('track', 'AddToCart', {
content_ids: [productId],
content_type: 'product'
});
}
}
});
});
})();
</script>
Limitation: Cannot easily access structured product data without Stencil. Recommend using Stencil method for full ecommerce tracking.
Method 3: Google Tag Manager Integration
If using GTM, fire Meta Pixel events based on data layer events.
Create Meta Pixel Event Tag in GTM
<script>
if (typeof fbq !== 'undefined') {
fbq('track', 'AddToCart', {
content_ids: [{{Product ID}}],
content_name: {{Product Name}},
value: {{Product Price}},
currency: {{Currency}},
content_type: 'product'
});
}
</script>
Trigger: Custom Event =
addToCart(from data layer)Use GTM Variables for dynamic values (Product ID, Name, Price from data layer)
Custom Events for BigCommerce
Beyond standard events, track BigCommerce-specific interactions.
Track Product Quick View
document.addEventListener('click', function(e) {
const quickViewBtn = e.target.closest('[data-quick-view]');
if (quickViewBtn && typeof fbq !== 'undefined') {
const productId = quickViewBtn.getAttribute('data-product-id');
const productName = quickViewBtn.getAttribute('data-product-name');
fbq('trackCustom', 'ProductQuickView', {
content_ids: [productId],
content_name: productName,
content_type: 'product'
});
}
});
Track Product Compare
document.addEventListener('click', function(e) {
const compareBtn = e.target.closest('[data-compare-add]');
if (compareBtn && typeof fbq !== 'undefined') {
const productId = compareBtn.getAttribute('data-product-id');
fbq('trackCustom', 'ProductCompare', {
content_ids: [productId],
content_type: 'product'
});
}
});
Track Newsletter Signup
document.addEventListener('DOMContentLoaded', function() {
const newsletterForm = document.querySelector('form[action*="subscribe"]') ||
document.querySelector('.newsletter-form');
if (newsletterForm) {
newsletterForm.addEventListener('submit', function() {
if (typeof fbq !== 'undefined') {
fbq('track', 'Lead', {
content_category: 'newsletter',
content_name: 'Newsletter Signup'
});
}
});
}
});
Track Account Registration
// Add to account registration page
document.addEventListener('DOMContentLoaded', function() {
const registrationForm = document.querySelector('[data-create-account-form]');
if (registrationForm) {
registrationForm.addEventListener('submit', function() {
if (typeof fbq !== 'undefined') {
fbq('track', 'CompleteRegistration', {
content_name: 'Account Registration',
status: 'submitted'
});
}
});
}
});
Track Coupon Application
document.addEventListener('DOMContentLoaded', function() {
const couponForm = document.querySelector('[data-coupon-code-form]');
if (couponForm) {
couponForm.addEventListener('submit', function() {
const couponInput = this.querySelector('input[name="couponcode"]');
const couponCode = couponInput?.value;
if (typeof fbq !== 'undefined' && couponCode) {
fbq('trackCustom', 'CouponApplied', {
coupon_code: couponCode
});
}
});
}
});
Track Product Review Submission
document.addEventListener('DOMContentLoaded', function() {
const reviewForm = document.querySelector('[data-product-review-form]');
if (reviewForm) {
reviewForm.addEventListener('submit', function() {
const productId = this.getAttribute('data-product-id');
const rating = this.querySelector('input[name="rating"]:checked')?.value;
if (typeof fbq !== 'undefined') {
fbq('trackCustom', 'ProductReview', {
content_ids: [productId],
content_type: 'product',
rating: rating
});
}
});
}
});
Advanced Event Parameters
Use Enhanced Match Parameters
Include customer data for better ad matching:
fbq('track', 'Purchase', {
value: 99.99,
currency: 'USD',
content_ids: ['123'],
content_type: 'product'
}, {
em: 'customer@example.com', // Email
fn: 'john', // First name
ln: 'smith', // Last name
ph: '5551234567', // Phone
ct: 'menlopark', // City
st: 'ca', // State
zp: '94025', // ZIP
country: 'us' // Country
});
In Stencil templates:
{{#if customer}}
fbq('track', 'AddToCart', {
value: {{product.price}},
currency: '{{currency.code}}',
content_ids: ['{{product.id}}'],
content_type: 'product'
}, {
em: '{{customer.email}}',
fn: '{{customer.first_name}}',
ln: '{{customer.last_name}}',
ct: '{{customer.city}}',
st: '{{customer.state}}',
zp: '{{customer.zip}}',
country: '{{customer.country_code}}'
});
{{else}}
fbq('track', 'AddToCart', {
value: {{product.price}},
currency: '{{currency.code}}',
content_ids: ['{{product.id}}'],
content_type: 'product'
});
{{/if}}
Dynamic Product Ads Parameters
For Dynamic Product Ads (DPA), include structured product data:
fbq('track', 'ViewContent', {
content_ids: ['{{product.id}}'],
content_name: '{{product.name}}',
content_type: 'product',
value: {{product.price}},
currency: '{{currency.code}}',
// DPA-specific parameters
content_category: '{{product.category}}',
availability: '{{product.availability}}', // in stock, out of stock, preorder
condition: '{{product.condition}}', // new, refurbished, used
description: '{{product.description}}',
image_url: '{{product.image}}',
url: '{{product.url}}',
brand: '{{product.brand}}'
});
Event Deduplication
Prevent duplicate events when using both browser pixel and Conversions API.
Add Event ID
// Generate unique event ID
function generateEventId() {
return Date.now().toString(36) + Math.random().toString(36).substr(2);
}
var eventId = generateEventId();
// Track with event ID
fbq('track', 'Purchase', {
value: 99.99,
currency: 'USD',
content_ids: ['123']
}, {
eventID: eventId
});
// Send same event ID to Conversions API for deduplication
Testing Meta Pixel Events
1. Use Meta Pixel Helper
- Install Chrome extension
- Visit your store
- Perform tracked actions
- Verify events appear with correct parameters
- Check for warnings or errors
2. Test Events Tool in Events Manager
- Go to Events Manager > Test Events
- Enter your store URL
- Perform actions (view product, add to cart, etc.)
- Verify events appear in real-time with parameters
- Check parameter values are correct
3. Browser Console Debugging
// Enable debug mode
if (typeof fbq !== 'undefined') {
fbq('set', 'autoConfig', false, 'YOUR_PIXEL_ID');
console.log('Meta Pixel debug mode enabled');
}
// Log events
var originalFbq = fbq;
fbq = function() {
console.log('Meta Pixel Event:', arguments);
originalFbq.apply(this, arguments);
};
4. Verify in Browser Network Tab
- Open DevTools > Network
- Filter by "facebook.com"
- Perform tracked action
- Check request includes:
- Correct event name (
enparameter) - Event parameters (
cdparameter) - Pixel ID (
idparameter)
- Correct event name (
Best Practices
1. Use Standard Events When Possible
Prefer standard events over custom events:
// GOOD: Standard event
fbq('track', 'AddToCart', {...});
// BAD: Custom event for standard action
fbq('trackCustom', 'ProductAddedToCart', {...});
2. Always Include Value and Currency
For all commerce events:
fbq('track', 'AddToCart', {
value: 29.99, // Required
currency: 'USD', // Required
content_ids: ['123'], // Required
content_type: 'product' // Required
});
3. Send Product IDs as Strings
// GOOD: String IDs
content_ids: ['123', '456']
// BAD: Numeric IDs
content_ids: [123, 456]
4. Use Contents Parameter for Multiple Products
fbq('track', 'Purchase', {
value: 149.97,
currency: 'USD',
content_ids: ['123', '456', '789'],
content_type: 'product',
contents: [
{id: '123', quantity: 2, item_price: 29.99},
{id: '456', quantity: 1, item_price: 49.99},
{id: '789', quantity: 1, item_price: 39.99}
]
});
5. Throttle High-Frequency Events
For events that can fire rapidly:
function throttle(func, delay) {
let timeoutId;
let lastExecTime = 0;
return function(...args) {
const currentTime = Date.now();
if (currentTime - lastExecTime >= delay) {
lastExecTime = currentTime;
func.apply(this, args);
} else {
clearTimeout(timeoutId);
timeoutId = setTimeout(() => {
lastExecTime = Date.now();
func.apply(this, args);
}, delay - (currentTime - lastExecTime));
}
};
}
// Usage
const trackSearch = throttle(function(query) {
fbq('track', 'Search', {search_string: query});
}, 1000);
Troubleshooting
Events Not Appearing in Events Manager
- Check pixel is loaded: Use Meta Pixel Helper
- Verify event syntax: Check event name and parameter spelling
- Allow processing time: Events can take 20-30 minutes to appear
- Check for errors: Open browser console for JavaScript errors
- Disable ad blockers: Test in incognito with extensions disabled
Incorrect Event Parameters
- Inspect network request: Check DevTools Network tab
- Verify data types: Ensure strings, numbers match Meta's requirements
- Check Stencil context: Verify data is available in template
- Use console logging: Log values before sending to pixel
Events Firing Multiple Times
- Check for duplicate pixel code: Remove from theme if in Script Manager
- Verify event listeners: Ensure listeners attached only once
- Check GTM tag firing: Verify triggers aren't overlapping
- Use event deduplication: Implement event IDs