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