Meta Pixel Setup on PrestaShop
Implement Meta Pixel (formerly Facebook Pixel) on your PrestaShop store to track conversions, optimize ads, and build targeted audiences for Facebook and Instagram advertising.
Before You Begin
Prerequisites
- PrestaShop Version: 1.7.x or 8.x
- Meta Business Account: business.facebook.com
- Meta Pixel ID: 15-digit number from Events Manager
- Facebook Page: Connected to your Business Account
- Catalog (Optional): For dynamic product ads
- GDPR Compliance: Cookie consent mechanism
What is Meta Pixel?
Meta Pixel is a JavaScript code that tracks visitor actions on your website. It enables:
- Conversion Tracking: Measure purchase, add to cart, checkout events
- Audience Building: Create custom audiences from website visitors
- Ad Optimization: Optimize ads for conversions using pixel data
- Dynamic Ads: Show products people viewed on your store
- Attribution: Track customer journey across Facebook/Instagram and your store
Method 1: Using PrestaShop Modules
Option A: Official Facebook & Instagram Module
PrestaShop Official Facebook Integration:
Step 1: Install Module
- Navigate to Modules > Module Manager
- Search for "Facebook" or "Facebook & Instagram"
- Install official Facebook module
- Click Configure
Step 2: Connect to Facebook
- Click Connect to Facebook
- Log in with Facebook Business account
- Grant requested permissions
- Select your Facebook Business Manager
- Select Facebook Page associated with store
- Select or create Meta Pixel
Step 3: Configure Settings
Configuration Options:
✓ Enable Pixel: Yes
✓ Pixel ID: [Auto-populated or enter manually]
✓ Enable Advanced Matching: Yes (recommended)
✓ Catalog Sync: Enable for dynamic ads
✓ Product Sets: Configure for targeted ads
Step 4: Enable Events
Standard events enabled by default:
- PageView
- ViewContent (product pages)
- AddToCart
- InitiateCheckout
- Purchase
Step 5: Verify Installation
- Install Meta Pixel Helper Chrome extension
- Visit your PrestaShop store
- Check extension shows pixel firing
- Verify events in Facebook Events Manager
Option B: Third-Party Meta Pixel Modules
Popular Premium Modules:
Presta Module's Enhanced Meta Pixel
- Price: ~$49-79
- Features: Server-side events, CAPI integration, custom events
- Best for: Advanced tracking, iOS 14+ optimization
eBusiness Guru Facebook Pixel Pro
- Price: ~$59
- Features: Multiple pixels, GTM integration, consent management
- Best for: Multi-store, agency use
Installation Steps:
- Purchase and download module ZIP
- Upload via Modules > Module Manager > Upload
- Install and configure
- Enter Pixel ID and access token (for CAPI)
- Enable desired events
- Test installation
Module Evaluation Checklist:
- PrestaShop version compatibility
- Server-side tracking (Conversions API) support
- Multi-pixel capability (for different ad accounts)
- GDPR/cookie consent integration
- Advanced matching (email, phone hashing)
- Recent updates and support responsiveness
Option C: Free Community Modules
GitHub/Community Options:
- Check PrestaShop forums
- Review GitHub repositories
- Verify module maintenance
- Test thoroughly in staging
- Check for GDPR compliance
Method 2: Manual Meta Pixel Implementation
For complete control over pixel implementation.
Create Custom Meta Pixel Module
Module Structure:
modules/custommeta/
├── custommeta.php
├── config.xml
├── logo.png
└── views/
└── templates/
└── hook/
├── pixel-base.tpl
└── pixel-events.tpl
Main Module File:
<?php
// modules/custommeta/custommeta.php
if (!defined('_PS_VERSION_')) {
exit;
}
class CustomMeta extends Module
{
public function __construct()
{
$this->name = 'custommeta';
$this->tab = 'advertising_marketing';
$this->version = '1.0.0';
$this->author = 'Your Name';
$this->need_instance = 0;
$this->bootstrap = true;
parent::__construct();
$this->displayName = $this->l('Custom Meta Pixel');
$this->description = $this->l('Integrate Meta Pixel (Facebook Pixel) with PrestaShop');
$this->ps_versions_compliancy = array('min' => '1.7', 'max' => _PS_VERSION_);
}
public function install()
{
Configuration::updateValue('CUSTOMMETA_PIXEL_ID', '');
Configuration::updateValue('CUSTOMMETA_ENABLED', 0);
Configuration::updateValue('CUSTOMMETA_ADVANCED_MATCHING', 1);
return parent::install()
&& $this->registerHook('displayHeader')
&& $this->registerHook('displayFooterProduct')
&& $this->registerHook('displayShoppingCart')
&& $this->registerHook('displayOrderConfirmation');
}
public function uninstall()
{
Configuration::deleteByName('CUSTOMMETA_PIXEL_ID');
Configuration::deleteByName('CUSTOMMETA_ENABLED');
Configuration::deleteByName('CUSTOMMETA_ADVANCED_MATCHING');
return parent::uninstall();
}
public function getContent()
{
$output = '';
if (Tools::isSubmit('submitCustomMeta')) {
$pixel_id = Tools::getValue('CUSTOMMETA_PIXEL_ID');
// Validate Pixel ID (15-digit number)
if (!preg_match('/^\d{15}$/', $pixel_id)) {
$output .= $this->displayError($this->l('Invalid Meta Pixel ID. Should be 15 digits.'));
} else {
Configuration::updateValue('CUSTOMMETA_PIXEL_ID', $pixel_id);
Configuration::updateValue('CUSTOMMETA_ENABLED', Tools::getValue('CUSTOMMETA_ENABLED'));
Configuration::updateValue('CUSTOMMETA_ADVANCED_MATCHING', Tools::getValue('CUSTOMMETA_ADVANCED_MATCHING'));
$output .= $this->displayConfirmation($this->l('Settings updated successfully'));
}
}
return $output . $this->renderForm();
}
protected function renderForm()
{
$fields_form = array(
'form' => array(
'legend' => array(
'title' => $this->l('Meta Pixel Settings'),
'icon' => 'icon-cogs'
),
'input' => array(
array(
'type' => 'switch',
'label' => $this->l('Enable Meta Pixel'),
'name' => 'CUSTOMMETA_ENABLED',
'is_bool' => true,
'values' => array(
array('id' => 'active_on', 'value' => 1, 'label' => $this->l('Yes')),
array('id' => 'active_off', 'value' => 0, 'label' => $this->l('No'))
)
),
array(
'type' => 'text',
'label' => $this->l('Meta Pixel ID'),
'name' => 'CUSTOMMETA_PIXEL_ID',
'required' => true,
'desc' => $this->l('Your 15-digit Meta Pixel ID from Events Manager'),
'placeholder' => '123456789012345'
),
array(
'type' => 'switch',
'label' => $this->l('Advanced Matching'),
'name' => 'CUSTOMMETA_ADVANCED_MATCHING',
'is_bool' => true,
'desc' => $this->l('Send hashed customer data for better matching (GDPR compliant)'),
'values' => array(
array('id' => 'active_on', 'value' => 1, 'label' => $this->l('Yes')),
array('id' => 'active_off', 'value' => 0, 'label' => $this->l('No'))
)
)
),
'submit' => array(
'title' => $this->l('Save'),
'class' => 'btn btn-default pull-right'
)
)
);
$helper = new HelperForm();
$helper->module = $this;
$helper->name_controller = $this->name;
$helper->token = Tools::getAdminTokenLite('AdminModules');
$helper->currentIndex = AdminController::$currentIndex . '&configure=' . $this->name;
$helper->submit_action = 'submitCustomMeta';
$helper->default_form_language = (int)Configuration::get('PS_LANG_DEFAULT');
$helper->fields_value['CUSTOMMETA_ENABLED'] = Configuration::get('CUSTOMMETA_ENABLED');
$helper->fields_value['CUSTOMMETA_PIXEL_ID'] = Configuration::get('CUSTOMMETA_PIXEL_ID');
$helper->fields_value['CUSTOMMETA_ADVANCED_MATCHING'] = Configuration::get('CUSTOMMETA_ADVANCED_MATCHING');
return $helper->generateForm(array($fields_form));
}
public function hookDisplayHeader($params)
{
if (!Configuration::get('CUSTOMMETA_ENABLED')) {
return '';
}
$pixel_id = Configuration::get('CUSTOMMETA_PIXEL_ID');
if (empty($pixel_id)) {
return '';
}
// Prepare advanced matching data
$advanced_matching = array();
if (Configuration::get('CUSTOMMETA_ADVANCED_MATCHING') && $this->context->customer->isLogged()) {
$customer = $this->context->customer;
// Hash customer data for privacy
$advanced_matching = array(
'em' => hash('sha256', strtolower(trim($customer->email))),
'fn' => hash('sha256', strtolower(trim($customer->firstname))),
'ln' => hash('sha256', strtolower(trim($customer->lastname))),
'ct' => hash('sha256', strtolower(trim($this->context->customer->getAddresses($this->context->language->id)[0]['city'] ?? ''))),
'country' => hash('sha256', strtolower(trim($this->context->country->iso_code)))
);
}
$this->context->smarty->assign(array(
'meta_pixel_id' => $pixel_id,
'meta_advanced_matching' => !empty($advanced_matching) ? json_encode($advanced_matching) : 'null'
));
return $this->display(__FILE__, 'views/templates/hook/pixel-base.tpl');
}
}
Base Pixel Template
{* modules/custommeta/views/templates/hook/pixel-base.tpl *}
<!-- Meta Pixel Code -->
<script>
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window, document,'script',
'https://connect.facebook.net/en_US/fbevents.js');
{if $meta_advanced_matching != 'null'}
fbq('init', '{$meta_pixel_id|escape:'javascript':'UTF-8'}', {$meta_advanced_matching nofilter});
{else}
fbq('init', '{$meta_pixel_id|escape:'javascript':'UTF-8'}');
{/if}
fbq('track', 'PageView');
</script>
<noscript>
<img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id={$meta_pixel_id|escape:'html':'UTF-8'}&ev=PageView&noscript=1"/>
</noscript>
<!-- End Meta Pixel Code -->
Method 3: GTM Implementation (Recommended)
Using Google Tag Manager provides more flexibility:
Step 1: Create Meta Pixel Tag in GTM
Tag Configuration:
Tag Type: Custom HTML
Tag Name: Meta Pixel - Base Code
HTML:
<!-- Meta Pixel Code -->
<script>
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window, document,'script',
'https://connect.facebook.net/en_US/fbevents.js');
fbq('init', 'YOUR_PIXEL_ID');
fbq('track', 'PageView');
</script>
<noscript>
<img height="1" width="1" style="display:none"
src="https://www.facebook.com/tr?id=YOUR_PIXEL_ID&ev=PageView&noscript=1"/>
</noscript>
Triggering: All Pages
Advantages:
- Easy to update without code changes
- Test in GTM preview mode
- Version control
- No PrestaShop cache issues
- Manage multiple pixels easily
Step 2: Create Event Tags
See Meta Pixel Event Tracking for detailed event implementation.
Advanced Matching Setup
Why Use Advanced Matching?
- Improves event attribution accuracy
- Better conversion tracking for iOS 14+
- Enhanced audience matching
- Complies with privacy standards (data is hashed)
Implementation:
// With hashed customer data
fbq('init', 'YOUR_PIXEL_ID', {
em: 'hashed_email', // SHA-256 hash of email
fn: 'hashed_firstname', // SHA-256 hash of first name
ln: 'hashed_lastname', // SHA-256 hash of last name
ph: 'hashed_phone', // SHA-256 hash of phone
ct: 'hashed_city', // SHA-256 hash of city
st: 'hashed_state', // SHA-256 hash of state
zp: 'hashed_zip', // SHA-256 hash of zip code
country: 'hashed_country' // SHA-256 hash of country code
});
PrestaShop Implementation:
// In hookDisplayHeader
if ($this->context->customer->isLogged()) {
$customer = $this->context->customer;
$address = new Address($customer->id_default_address);
$advanced_matching = array(
'em' => hash('sha256', strtolower(trim($customer->email))),
'fn' => hash('sha256', strtolower(trim($customer->firstname))),
'ln' => hash('sha256', strtolower(trim($customer->lastname))),
'ph' => hash('sha256', preg_replace('/[^0-9]/', '', $address->phone)),
'ct' => hash('sha256', strtolower(trim($address->city))),
'zp' => hash('sha256', trim($address->postcode)),
'country' => hash('sha256', strtolower(trim($this->context->country->iso_code)))
);
}
Multi-Store Configuration
Scenario 1: Different Pixels Per Store
For separate ad accounts or brands:
// Map shop IDs to Pixel IDs
$shop_id = $this->context->shop->id;
$pixel_ids = array(
1 => '111111111111111', // Main store
2 => '222222222222222', // Second brand
3 => '333333333333333' // Regional store
);
$pixel_id = isset($pixel_ids[$shop_id]) ? $pixel_ids[$shop_id] : Configuration::get('CUSTOMMETA_PIXEL_ID');
Scenario 2: Multiple Pixels on Same Store
For agencies managing multiple clients:
// Initialize multiple pixels
fbq('init', 'PIXEL_ID_1');
fbq('init', 'PIXEL_ID_2');
fbq('init', 'PIXEL_ID_3');
// Track events to all pixels
fbq('track', 'PageView');
GDPR Compliance & Consent Management
Cookie Consent Integration
Must implement for EU stores:
// Only load pixel after consent
document.addEventListener('DOMContentLoaded', function() {
// Check for cookie consent
if (typeof prestashop !== 'undefined' && prestashop.gdprConsent) {
if (prestashop.gdprConsent.marketing) {
loadMetaPixel();
}
}
// Listen for consent changes
document.addEventListener('cookieConsentGranted', function(e) {
if (e.detail.marketing) {
loadMetaPixel();
}
});
});
function loadMetaPixel() {
!function(f,b,e,v,n,t,s)
{if(f.fbq)return;n=f.fbq=function(){n.callMethod?
n.callMethod.apply(n,arguments):n.queue.push(arguments)};
if(!f._fbq)f._fbq=n;n.push=n;n.loaded=!0;n.version='2.0';
n.queue=[];t=b.createElement(e);t.async=!0;
t.src=v;s=b.getElementsByTagName(e)[0];
s.parentNode.insertBefore(t,s)}(window, document,'script',
'https://connect.facebook.net/en_US/fbevents.js');
fbq('init', 'YOUR_PIXEL_ID');
fbq('track', 'PageView');
}
Limited Data Use (California Privacy)
For CCPA compliance:
// Set limited data use for California users
fbq('dataProcessingOptions', ['LDU'], 1, 1000); // California, USA
Testing Meta Pixel Installation
Using Meta Pixel Helper
Chrome Extension:
- Install Meta Pixel Helper from Chrome Web Store
- Navigate to your PrestaShop store
- Click extension icon
- Verify:
- ✅ Pixel found
- ✅ No errors
- ✅ Events firing correctly
Facebook Test Events Tool
In Events Manager:
- Go to Events Manager > Test Events
- Enter your website URL or use browser extension
- Browse your store
- Verify events appear in real-time
- Check event parameters are correct
Browser Console Testing
// Check if pixel loaded
typeof fbq !== 'undefined'
// Returns: true
// Check pixel queue
fbq.queue
// Returns: Array of queued events
// Manually fire test event
fbq('track', 'ViewContent', {
content_name: 'Test Product',
content_ids: ['12345'],
value: 29.99,
currency: 'USD'
});
Troubleshooting
Pixel Not Loading
Check:
- Pixel ID is correct 15-digit format
- Module is enabled
- PrestaShop cache cleared
- No ad blockers (for testing)
- Check browser console for errors
Debug:
// Check if fbevents.js loaded
document.querySelector('script[src*="fbevents.js"]')
// Should return script element
Events Not Firing
Common Issues:
- Pixel base code not loaded before events
- Cookie consent blocking pixel
- JavaScript errors preventing execution
- Module hook not registered
Debug:
// Enable debug mode
fbq('set', 'autoConfig', false, 'YOUR_PIXEL_ID');
Advanced Matching Not Working
Check:
- Data is properly hashed with SHA-256
- No extra whitespace in values
- Email is lowercase before hashing
- Customer is logged in
Test:
// Check advanced matching data
fbq.getState().pixels['YOUR_PIXEL_ID'].userData
// Should show hashed values
Performance Optimization
Async Loading
Meta Pixel loads asynchronously by default, but optimize further:
// Defer pixel loading until user interaction
var pixelLoaded = false;
function loadPixelOnInteraction() {
if (!pixelLoaded) {
loadMetaPixel();
pixelLoaded = true;
}
}
// Load on scroll, click, or after delay
window.addEventListener('scroll', loadPixelOnInteraction, { once: true });
window.addEventListener('click', loadPixelOnInteraction, { once: true });
setTimeout(loadPixelOnInteraction, 3000); // Fallback after 3s
Reduce Pixel Size
- Only load required events
- Remove noscript fallback if not needed
- Minify custom event code
Next Steps
Now that Meta Pixel is installed:
- Meta Pixel Event Tracking - Implement conversion events
- GTM Setup - Manage pixel via GTM
- Events Not Firing - Debug tracking issues
For Facebook Catalog setup:
- Configure product feed in PrestaShop
- Upload catalog to Facebook Commerce Manager
- Enable dynamic product ads