Install Meta Pixel on MODX (Step-by-Step) | OpsBlu Docs

Install Meta Pixel on MODX (Step-by-Step)

How to install Meta (Facebook) Pixel on MODX Revolution using templates, plugins, or Google Tag Manager.

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:

  1. Meta Business Account: Create at business.facebook.com
  2. Meta Pixel: Create pixel in Events Manager
  3. Pixel ID: Copy your 16-digit Pixel ID
  4. MODX Access: Manager access to edit templates or install plugins

Method 1: Template-Based Implementation

Add Meta Pixel directly to MODX templates.

Installation Steps

  1. Access Template Manager

    • Log into MODX Manager
    • Go to ElementsTemplates
    • Click on your base template
  2. 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_ID with your actual Meta Pixel ID.

  3. 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 -->
    
  4. Create Reusable Chunk (Optional)

    For easier management:

    a. Go to ElementsChunksCreate New b. Name: meta_pixel c. Add Meta Pixel code from step 3 d. In templates, use:

    <head>
      [[$meta_pixel]]
    </head>
    
  5. Save and Clear Cache

    • Click Save
    • ManageClear Cache
    • Test on your site

Verify Installation

  1. Install Meta Pixel Helper browser extension
  2. Visit your MODX site
  3. Click Pixel Helper icon
  4. Should show green checkmark with your Pixel ID
  5. Verify PageView event fires

Method 2: Plugin-Based Implementation

Use MODX plugin to automatically inject Meta Pixel.

Custom Plugin Setup

  1. Create New Plugin

    • Go to ElementsPlugins
    • Click Create New Plugin
    • Name: Meta Pixel Injector
  2. 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;
    
  3. Set System Events

    • Click System Events tab
    • Check: OnWebPagePrerender
    • Save plugin
  4. Enable and Test

    • Enable plugin
    • Clear cache
    • Test with Meta Pixel Helper

Install Meta Pixel through GTM for easier management.

Setup Steps

  1. Install GTM on MODX

    See Install Google Tag Manager for full installation.

  2. Create Meta Pixel Tag in GTM

    a. In GTM, go to TagsNew

    b. Click Tag ConfigurationCustom 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"

  3. 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>
    
  4. Publish Container

    • Click Submit
    • Add version name
    • Click Publish
  5. 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

  1. Go to Meta Events Manager
  2. Select your Pixel
  3. Click Test Events tab
  4. Enter your MODX site URL
  5. Perform actions on site
  6. 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, AddToCart
  • InitiateCheckout, AddPaymentInfo, Purchase
  • Lead, 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

For general Meta Pixel concepts, see Meta Pixel Guide.