Install Meta Pixel (Facebook Pixel) on your MODX website to track conversions, optimize ads, and build targeted audiences.
Installation Methods
| Method | Difficulty | Customization | Maintenance | Recommended For |
|---|---|---|---|---|
| Template Code | Easy | High | Manual | Direct control, custom events |
| Plugin/Extra | Medium | Medium | Auto-updates | Standard setup, easier management |
| Google Tag Manager | Medium | Highest | Via GTM | Most sites (recommended) |
Prerequisites
Before installation:
- Meta Business Account: Create at business.facebook.com
- Meta Pixel: Create pixel in Events Manager
- Pixel ID: Copy your 16-digit Pixel ID
- MODX Access: Manager access to edit templates or install plugins
Method 1: Template-Based Implementation
Add Meta Pixel directly to MODX templates.
Installation Steps
Access Template Manager
- Log into MODX Manager
- Go to Elements → Templates
- Click on your base template
Add Meta Pixel Base Code
Find the
</head>tag and add above it:<!-- 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> <!-- End Meta Pixel Code -->Replace
YOUR_PIXEL_IDwith your actual Meta Pixel ID.Add MODX-Specific Parameters
Enhance tracking with MODX resource data:
<!-- Meta Pixel Code with MODX Data --> <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', { external_id: '[[!+modx.user.id:notempty=`[[!+modx.user.id]]`]]', em: '[[!+modx.user.email:notempty=`[[!+modx.user.email]]`]]' }); fbq('track', 'PageView', { content_name: '[[*pagetitle]]', content_category: '[[*parent:is=`0`:then=`Homepage`:else=`[[*parent:select=`pagetitle`]]`]]', resource_id: '[[*id]]', template: '[[*template]]' }); </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> <!-- End Meta Pixel Code -->Create Reusable Chunk (Optional)
For easier management:
a. Go to Elements → Chunks → Create New b. Name:
meta_pixelc. Add Meta Pixel code from step 3 d. In templates, use:<head> [[$meta_pixel]] </head>Save and Clear Cache
- Click Save
- Manage → Clear Cache
- Test on your site
Verify Installation
- Install Meta Pixel Helper browser extension
- Visit your MODX site
- Click Pixel Helper icon
- Should show green checkmark with your Pixel ID
- Verify PageView event fires
Method 2: Plugin-Based Implementation
Use MODX plugin to automatically inject Meta Pixel.
Custom Plugin Setup
Create New Plugin
- Go to Elements → Plugins
- Click Create New Plugin
- Name:
Meta Pixel Injector
Plugin Code
<?php /** * Meta Pixel Injector Plugin * Automatically adds Meta Pixel to all pages * * System Events: OnWebPagePrerender */ $pixelId = 'YOUR_PIXEL_ID'; // Replace with your Pixel ID $resource = $modx->resource; $user = $modx->user; // Build user data (if logged in) $userData = []; if ($user->isAuthenticated('web')) { $userData['external_id'] = $user->get('id'); $userData['em'] = $user->get('email'); } $userDataJson = json_encode($userData); // Build page data $pageData = [ 'content_name' => $resource->get('pagetitle'), 'resource_id' => $resource->get('id'), 'template' => $resource->get('template') ]; // Add parent title if exists if ($resource->get('parent') > 0) { $parent = $modx->getObject('modResource', $resource->get('parent')); if ($parent) { $pageData['content_category'] = $parent->get('pagetitle'); } } $pageDataJson = json_encode($pageData); $metaPixelCode = <<<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', '{$pixelId}', {$userDataJson}); fbq('track', 'PageView', {$pageDataJson}); </script> <noscript> <img height="1" width="1" style="display:none" src="https://www.facebook.com/tr?id={$pixelId}&ev=PageView&noscript=1"/> </noscript> <!-- End Meta Pixel Code --> HTML; // Inject before </head> $output = $modx->resource->_output; $output = str_replace('</head>', $metaPixelCode . '</head>', $output); $modx->resource->_output = $output;Set System Events
- Click System Events tab
- Check:
OnWebPagePrerender - Save plugin
Enable and Test
- Enable plugin
- Clear cache
- Test with Meta Pixel Helper
Method 3: Google Tag Manager (Recommended)
Install Meta Pixel through GTM for easier management.
Setup Steps
Install GTM on MODX
See Install Google Tag Manager for full installation.
Create Meta Pixel Tag in GTM
a. In GTM, go to Tags → New
b. Click Tag Configuration → Custom HTML
c. Paste Meta Pixel base 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>d. Triggering: Select All Pages
e. Save and name "Meta Pixel - Base Code"
Add MODX Data Layer Variables
Use MODX data layer variables in Pixel events:
<script> fbq('init', 'YOUR_PIXEL_ID'); fbq('track', 'PageView', { content_name: {{DLV - Page Title}}, resource_id: {{DLV - Resource ID}}, content_category: {{DLV - Parent Title}} }); </script>Publish Container
- Click Submit
- Add version name
- Click Publish
Test
- Use GTM Preview mode
- Verify Meta Pixel tag fires
- Check with Meta Pixel Helper
Standard Events Implementation
ViewContent Event
Track content page views:
<script>
[[*template:isnot=`1`:then=`
fbq('track', 'ViewContent', {
content_name: '[[*pagetitle]]',
content_ids: ['[[*id]]'],
content_type: 'product',
content_category: '[[*parent:select=`pagetitle`]]'
});
`]]
</script>
Contact Event (Form View)
Track when contact form is viewed:
<!-- On contact page template -->
<script>
[[*template:is=`4`:then=`
fbq('track', 'Contact', {
content_name: '[[*pagetitle]]',
resource_id: '[[*id]]'
});
`]]
</script>
Lead Event (Form Submission)
Track form submissions using FormIt:
[[!FormIt?
&hooks=`email,FormItSaveForm`
&emailTo=`info@example.com`
]]
<form id="contact-form" action="[[~[[*id]]]]" method="post">
<!-- Form fields -->
<button type="submit">Submit</button>
</form>
<!-- Track lead event on success -->
[[!+fi.successMessage:notempty=`
<script>
fbq('track', 'Lead', {
content_name: 'Contact Form',
content_category: 'Lead Form',
resource_id: '[[*id]]'
});
</script>
`]]
Search Event
Track site searches:
[[!SimpleSearch?
&landing=`[[*id]]`
]]
<form action="[[~[[*id]]]]" method="get">
<input type="text" name="search" value="[[!+search]]" placeholder="Search...">
<button type="submit">Search</button>
</form>
<!-- Track search -->
[[!+search:notempty=`
<script>
fbq('track', 'Search', {
search_string: '[[!+search]]',
content_category: 'Site Search',
resource_id: '[[*id]]'
});
</script>
`]]
E-Commerce Events (MiniShop2)
For MODX e-commerce sites using MiniShop2:
ViewContent (Product Page)
<!-- On product template -->
<script>
fbq('track', 'ViewContent', {
content_name: '[[*pagetitle]]',
content_ids: ['[[*id]]'],
content_type: 'product',
value: [[*price:default=`0`]],
currency: '[[++minishop2.currency:default=`USD`]]'
});
</script>
AddToCart Event
<script>
// Listen for MiniShop2 add to cart
document.addEventListener('msminicart:add', function(e) {
fbq('track', 'AddToCart', {
content_name: e.detail.name,
content_ids: [e.detail.id],
content_type: 'product',
value: e.detail.price * e.detail.count,
currency: '[[++minishop2.currency]]'
});
});
</script>
InitiateCheckout Event
<!-- On cart/checkout page -->
<script>
[[*template:is=`5`:then=`
fbq('track', 'InitiateCheckout', {
content_category: 'Checkout',
num_items: [[!+ms2_total_count]],
value: [[!+ms2_total_cost]],
currency: '[[++minishop2.currency]]'
});
`]]
</script>
Purchase Event
<!-- Order confirmation template -->
[[!msOrder? &to=`orderConfirmation.tpl`]]
<!-- In orderConfirmation.tpl chunk -->
<script>
fbq('track', 'Purchase', {
content_type: 'product',
content_ids: [[[+product_ids]]], // Array of product IDs
value: [[+cost]],
currency: '[[++minishop2.currency]]',
num_items: [[+product_count]]
});
</script>
Advanced Configuration
Enhanced Matching (Privacy-Compliant)
Send hashed user data for better matching:
<?php
// In plugin
$userData = [];
if ($user->isAuthenticated('web')) {
// Hash email and phone
$email = strtolower(trim($user->get('email')));
$userData['em'] = hash('sha256', $email);
$phone = preg_replace('/[^0-9]/', '', $user->getOne('Profile')->get('phone'));
if ($phone) {
$userData['ph'] = hash('sha256', $phone);
}
// Other fields
$userData['external_id'] = $user->get('id');
}
Custom Events
Track custom MODX-specific events:
<script>
// Custom event: Resource downloaded
document.addEventListener('click', function(e) {
const link = e.target.closest('a[href$=".pdf"]');
if (link) {
fbq('trackCustom', 'DownloadResource', {
resource_name: link.textContent,
resource_url: link.href,
resource_id: '[[*id]]'
});
}
});
</script>
Conditional Pixel Loading
Load different pixels based on context or template:
[[switch? &value=`[[!++context_key]]`
&case=`web=YOUR_WEB_PIXEL_ID`
&case=`mobile=YOUR_MOBILE_PIXEL_ID`
&default=`YOUR_DEFAULT_PIXEL_ID`
]]
Conversions API (Server-Side Tracking)
For better tracking accuracy, implement Conversions API:
MODX Plugin for CAPI
<?php
/**
* Meta Conversions API Plugin
* Send server-side events to Meta
*
* System Events: OnWebPageComplete
*/
$pixelId = 'YOUR_PIXEL_ID';
$accessToken = 'YOUR_CAPI_ACCESS_TOKEN';
// Build event data
$eventData = [
'event_name' => 'PageView',
'event_time' => time(),
'event_source_url' => $modx->makeUrl($modx->resource->get('id'), '', '', 'full'),
'user_data' => [
'client_ip_address' => $_SERVER['REMOTE_ADDR'],
'client_user_agent' => $_SERVER['HTTP_USER_AGENT']
],
'custom_data' => [
'resource_id' => $modx->resource->get('id'),
'template' => $modx->resource->get('template')
]
];
// Add user data if logged in
if ($modx->user->isAuthenticated('web')) {
$email = strtolower(trim($modx->user->get('email')));
$eventData['user_data']['em'] = hash('sha256', $email);
$eventData['user_data']['external_id'] = $modx->user->get('id');
}
// Send to Meta CAPI
$url = "https://graph.facebook.com/v18.0/{$pixelId}/events";
$data = [
'data' => [$eventData],
'access_token' => $accessToken
];
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
$response = curl_exec($ch);
curl_close($ch);
// Log response (optional)
$modx->log(modX::LOG_LEVEL_INFO, 'Meta CAPI Response: ' . $response);
Verification & Testing
1. Meta Pixel Helper
- Install Meta Pixel Helper
- Visit your MODX site
- Check for green checkmark
- View events firing in real-time
2. Events Manager Test Events
- Go to Meta Events Manager
- Select your Pixel
- Click Test Events tab
- Enter your MODX site URL
- Perform actions on site
- Verify events appear in Events Manager
3. Browser Console
// Check if fbq is loaded
console.log(typeof fbq); // Should be "function"
// View pixel queue
console.log(fbq.queue);
Troubleshooting
Pixel Not Loading
Check:
- Pixel ID is correct (16-digit number)
- No JavaScript errors in console
- Ad blocker is disabled (for testing)
- MODX cache is cleared
Console check:
console.log(typeof fbq); // Should be "function", not "undefined"
Events Not Firing
See Events Not Firing for detailed debugging.
Quick checks:
- Meta Pixel Helper shows pixel loaded
- Events appear in Test Events
- No JavaScript errors
- Event parameters formatted correctly
MODX Placeholders Not Resolving
Issue: Placeholders show as literal text.
Fix:
// Ensure proper MODX syntax
[[*id]] // Correct
{*id} // Wrong
// Use output filters for fallbacks
[[*price:default=`0`]]
[[*pagetitle:notempty=`[[*pagetitle]]`:default=`Untitled`]]
Duplicate Events
Cause: Multiple implementations (template + plugin).
Fix: Choose ONE method and remove others.
Best Practices
1. Hash Personally Identifiable Information (PII)
// Hash email before sending
$email = strtolower(trim($email));
$hashedEmail = hash('sha256', $email);
2. Use Standard Event Names
Follow Meta's standard events:
PageView,ViewContent,Search,AddToCartInitiateCheckout,AddPaymentInfo,PurchaseLead,CompleteRegistration,Contact
3. Include Event Parameters
Always include relevant parameters:
fbq('track', 'ViewContent', {
content_name: 'Product Name',
content_ids: ['123'],
content_type: 'product',
value: 29.99,
currency: 'USD'
});
4. Test Thoroughly
- Test with Meta Pixel Helper
- Verify in Events Manager
- Test across different templates
- Check mobile devices
Next Steps
- GTM Setup - Manage Meta Pixel via GTM
- MODX Data Layer - Pass MODX data to Meta Pixel
- Events Not Firing - Debug tracking issues
For general Meta Pixel concepts, see Meta Pixel Guide.