Meta Pixel Setup on SilverStripe | OpsBlu Docs

Meta Pixel Setup on SilverStripe

Implement Meta (Facebook) Pixel on SilverStripe for ads tracking, retargeting, and conversion optimization.

Implement Meta (Facebook) Pixel on your SilverStripe site to track conversions, build audiences, and optimize Facebook and Instagram ad campaigns.

Prerequisites

  • Facebook Business Account and Meta Pixel created
  • Meta Pixel ID (15-16 digit number)
  • SilverStripe CMS access
  • Access to SilverStripe templates

Step 1: Create Pixel Include Template

File: themes/yourtheme/templates/Includes/MetaPixel.ss

<% if $SiteConfig.MetaPixelID %>
<!-- 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', '{$SiteConfig.MetaPixelID}');
fbq('track', 'PageView');

<% if $CurrentMember %>
fbq('setUserData', {
  em: '{$CurrentMember.Email}',
  fn: '{$CurrentMember.FirstName}',
  ln: '{$CurrentMember.Surname}'
});
<% end_if %>
</script>
<noscript>
  <img height="1" width="1" style="display:none"
       src="https://www.facebook.com/tr?id={$SiteConfig.MetaPixelID}&ev=PageView&noscript=1"/>
</noscript>
<!-- End Meta Pixel Code -->
<% end_if %>

Step 2: Add to Page Template

File: themes/yourtheme/templates/Page.ss

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8">
    <title>$Title</title>
    $MetaTags

    <% include MetaPixel %>
</head>
<body class="$ClassName">
    $Layout
</body>
</html>

Step 3: Add Pixel ID to SiteConfig

File: app/src/Extensions/SiteConfigExtension.php

<?php

namespace App\Extensions;

use SilverStripe\Forms\FieldList;
use SilverStripe\Forms\TextField;
use SilverStripe\ORM\DataExtension;

class SiteConfigExtension extends DataExtension
{
    private static $db = [
        'MetaPixelID' => 'Varchar(20)',
    ];

    public function updateCMSFields(FieldList $fields)
    {
        $fields->addFieldToTab(
            'Root.Analytics',
            TextField::create('MetaPixelID', 'Meta Pixel ID')
                ->setDescription('Your Facebook Pixel ID (numbers only)')
        );
    }
}

Step 4: Register Extension

File: app/_config/config.yml

SilverStripe\SiteConfig\SiteConfig:
  extensions:
    - App\Extensions\SiteConfigExtension

Step 5: Build and Configure

sake dev/build flush=1

Then in CMS: Settings > Analytics > Enter Pixel ID > Save


Method 2: Requirements API

File: app/src/PageController.php

<?php

namespace App;

use PageController as BasePageController;
use SilverStripe\View\Requirements;
use SilverStripe\SiteConfig\SiteConfig;

class PageController extends BasePageController
{
    protected function init()
    {
        parent::init();

        $pixelID = SiteConfig::current_site_config()->MetaPixelID;

        if ($pixelID) {
            $script = <<<JS
!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}');
fbq('track', 'PageView');
JS;

            Requirements::customScript($script, 'meta-pixel');
        }
    }
}

Tracking Standard Events

Form Submissions (Lead Event)

File: app/src/PageController.php

public function doSubmitContact($data, $form)
{
    // Process form...

    // Track lead event
    Requirements::customScript(<<<JS
if (typeof fbq !== 'undefined') {
    fbq('track', 'Lead', {
        content_name: 'Contact Form',
        content_category: 'Contact'
    });
}
JS
    );

    return $this->redirectBack();
}

Content Views

File: themes/yourtheme/templates/Layout/BlogPost.ss

<script>
if (typeof fbq !== 'undefined') {
    fbq('track', 'ViewContent', {
        content_name: '$Title.JS',
        content_category: '$Category.Title.JS',
        content_type: 'blog_post',
        content_ids: ['$ID']
    });
}
</script>

Member Registration Tracking

File: app/src/MemberExtension.php

<?php

namespace App;

use SilverStripe\ORM\DataExtension;
use SilverStripe\View\Requirements;

class MemberExtension extends DataExtension
{
    public function onAfterWrite()
    {
        parent::onAfterWrite();

        if ($this->owner->isChanged('ID')) {
            // New member registered
            Requirements::customScript(<<<JS
if (typeof fbq !== 'undefined') {
    fbq('track', 'CompleteRegistration', {
        content_name: 'Member Registration'
    });
}
JS
            );
        }
    }
}

Server-Side Events (Conversions API)

For accurate tracking beyond browser pixels:

File: app/src/Services/MetaConversionsAPI.php

<?php

namespace App\Services;

use SilverStripe\Core\Environment;

class MetaConversionsAPI
{
    public static function sendEvent($eventName, $eventData = [])
    {
        $pixelID = Environment::getEnv('META_PIXEL_ID');
        $accessToken = Environment::getEnv('META_CONVERSIONS_API_TOKEN');

        if (!$pixelID || !$accessToken) {
            return false;
        }

        $eventData = array_merge([
            'event_name' => $eventName,
            'event_time' => time(),
            'action_source' => 'website',
        ], $eventData);

        $ch = curl_init("https://graph.facebook.com/v18.0/{$pixelID}/events");
        curl_setopt($ch, CURLOPT_POST, 1);
        curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode([
            'data' => [$eventData],
            'access_token' => $accessToken,
        ]));
        curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

        $response = curl_exec($ch);
        curl_close($ch);

        return $response;
    }
}

Usage:

use App\Services\MetaConversionsAPI;

// In form handler
MetaConversionsAPI::sendEvent('Lead', [
    'user_data' => [
        'em' => [hash('sha256', strtolower(trim($data['Email'])))],
        'fn' => [hash('sha256', strtolower(trim($data['Name'])))],
    ],
    'custom_data' => [
        'content_name' => 'Contact Form',
    ],
]);

File: themes/yourtheme/templates/Includes/MetaPixel.ss

<script>
// Check for consent before loading pixel
if (localStorage.getItem('cookie_consent') === 'granted') {
    // Load pixel code...
    fbq('init', '{$SiteConfig.MetaPixelID}');
    fbq('track', 'PageView');
} else {
    // Pixel not loaded until consent
    fbq('consent', 'revoke');
}
</script>

Testing

Use Meta Pixel Helper

  1. Install Meta Pixel Helper Chrome Extension
  2. Visit your site
  3. Click extension
  4. Verify pixel detected

Check Events Manager

  1. Facebook Business Manager > Events Manager
  2. Select your Pixel
  3. Go to Test Events
  4. Verify events firing

Next Steps


Additional Resources