Install Meta Pixel on Strapi Sites | OpsBlu Docs

Install Meta Pixel on Strapi Sites

How to install Meta (Facebook) Pixel on Strapi-powered sites using Next.js, Gatsby, Nuxt, and other frontend frameworks.

Since Strapi is a headless CMS, Meta Pixel is installed on your frontend framework (Next.js, Gatsby, Nuxt.js, etc.), not in Strapi itself. This guide covers Meta Pixel installation and event tracking for Strapi-powered sites.

Important: Frontend Implementation

Remember:

  • Install Meta Pixel in your frontend application
  • Do NOT try to install in Strapi admin panel
  • Strapi provides content via API; tracking happens on frontend
  • Consider GTM for easier pixel management

Before You Begin

  1. Create a Meta Pixel

    • Go to Meta Events Manager
    • Create a new pixel or use existing one
    • Note your Pixel ID (15-16 digit number)
  2. Choose Your Implementation Method

Method 1: Next.js + Strapi

App Router (Next.js 13+)

1. Create Meta Pixel Component

// components/MetaPixel.tsx
'use client';

import Script from 'next/script';

interface MetaPixelProps {
  pixelId: string;
}

export default function MetaPixel({ pixelId }: MetaPixelProps) {
  return (
    <>
      <Script
        id="meta-pixel"
        strategy="afterInteractive"
        dangerouslySetInnerHTML={{
          __html: `
            !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');
          `,
        }}
      />
      <noscript>
        <img
          height="1"
          width="1"
          style={{ display: 'none' }}
          src={`https://www.facebook.com/tr?id=${pixelId}&ev=PageView&noscript=1`}
        />
      </noscript>
    </>
  );
}

2. Add to Root Layout

// app/layout.tsx
import MetaPixel from '@/components/MetaPixel';

export default function RootLayout({ children }: { children: React.ReactNode }) {
  return (
    <html lang="en">
      <body>
        {children}
        <MetaPixel pixelId={process.env.NEXT_PUBLIC_META_PIXEL_ID!} />
      </body>
    </html>
  );
}

3. Create Pixel Utility for Events

// lib/metaPixel.ts
declare global {
  interface Window {
    fbq: (...args: any[]) => void;
  }
}

export const trackMetaEvent = (eventName: string, params?: Record<string, any>) => {
  if (typeof window !== 'undefined' && window.fbq) {
    window.fbq('track', eventName, params);
  }
};

export const trackMetaCustomEvent = (eventName: string, params?: Record<string, any>) => {
  if (typeof window !== 'undefined' && window.fbq) {
    window.fbq('trackCustom', eventName, params);
  }
};

// Standard events
export const trackViewContent = (content: any) => {
  trackMetaEvent('ViewContent', {
    content_name: content.attributes?.title,
    content_category: content.attributes?.category?.data?.attributes?.name,
    content_ids: [content.id],
    content_type: 'product',
  });
};

export const trackSearch = (searchTerm: string) => {
  trackMetaEvent('Search', {
    search_string: searchTerm,
  });
};

4. Track Route Changes

// components/MetaPixelPageView.tsx
'use client';

import { usePathname, useSearchParams } from 'next/navigation';
import { useEffect } from 'react';

export default function MetaPixelPageView() {
  const pathname = usePathname();
  const searchParams = useSearchParams();

  useEffect(() => {
    if (typeof window !== 'undefined' && window.fbq) {
      window.fbq('track', 'PageView');
    }
  }, [pathname, searchParams]);

  return null;
}

Pages Router (Next.js 12 and earlier)

1. Add to _app.js

// pages/_app.js
import { useRouter } from 'next/router';
import { useEffect } from 'react';
import Script from 'next/script';

function MyApp({ Component, pageProps }) {
  const router = useRouter();
  const PIXEL_ID = process.env.NEXT_PUBLIC_META_PIXEL_ID;

  useEffect(() => {
    // Track page views on route change
    const handleRouteChange = () => {
      if (typeof window !== 'undefined' && window.fbq) {
        window.fbq('track', 'PageView');
      }
    };

    router.events.on('routeChangeComplete', handleRouteChange);
    return () => {
      router.events.off('routeChangeComplete', handleRouteChange);
    };
  }, [router.events]);

  return (
    <>
      {/* Meta Pixel Code */}
      <Script
        id="meta-pixel"
        strategy="afterInteractive"
        dangerouslySetInnerHTML={{
          __html: `
            !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', '${PIXEL_ID}');
            fbq('track', 'PageView');
          `,
        }}
      />
      <noscript>
        <img
          height="1"
          width="1"
          style={{ display: 'none' }}
          src={`https://www.facebook.com/tr?id=${PIXEL_ID}&ev=PageView&noscript=1`}
          alt=""
        />
      </noscript>
      <Component {...pageProps} />
    </>
  );
}

export default MyApp;

2. Track Strapi Content

// pages/articles/[slug].js
import { useEffect } from 'react';

export default function Article({ article }) {
  useEffect(() => {
    if (typeof window !== 'undefined' && window.fbq) {
      window.fbq('track', 'ViewContent', {
        content_name: article.attributes.title,
        content_category: article.attributes.category?.data?.attributes?.name,
        content_ids: [article.id],
        content_type: 'article',
      });
    }
  }, [article]);

  return (
    <article>
      <h1>{article.attributes.title}</h1>
      {/* Article content */}
    </article>
  );
}

Method 2: Gatsby + Strapi

Installation

npm install gatsby-plugin-facebook-pixel

Configuration

// gatsby-config.js
module.exports = {
  plugins: [
    {
      resolve: `gatsby-plugin-facebook-pixel`,
      options: {
        pixelId: process.env.META_PIXEL_ID,
      },
    },
    {
      resolve: 'gatsby-source-strapi',
      options: {
        apiURL: process.env.STRAPI_API_URL || 'http://localhost:1337',
        accessToken: process.env.STRAPI_TOKEN,
        collectionTypes: ['article', 'product'],
      },
    },
  ],
};

Track Events

// src/templates/article.js
import React, { useEffect } from 'react';

const ArticleTemplate = ({ data }) => {
  const article = data.strapiArticle;

  useEffect(() => {
    if (typeof window !== 'undefined' && window.fbq) {
      window.fbq('track', 'ViewContent', {
        content_name: article.title,
        content_ids: [article.strapiId],
        content_type: 'article',
      });
    }
  }, [article]);

  return (
    <article>
      <h1>{article.title}</h1>
      {/* Article content */}
    </article>
  );
};

export default ArticleTemplate;

Method 3: Nuxt.js + Strapi

Installation

npm install @nuxtjs/facebook-pixel

Configuration (Nuxt 2)

// nuxt.config.js
export default {
  modules: [
    '@nuxtjs/facebook-pixel',
  ],

  facebook: {
    pixelId: process.env.META_PIXEL_ID,
    track: 'PageView',
    version: '2.0',
    autoPageView: true,
  },
};

Configuration (Nuxt 3)

// nuxt.config.ts
export default defineNuxtConfig({
  modules: ['@nuxtjs/facebook-pixel'],

  facebookPixel: {
    pixelId: process.env.META_PIXEL_ID || '',
    track: 'PageView',
    version: '2.0',
  },
});

Track Events

<!-- pages/articles/[slug].vue -->
<script setup>
const { $fb } = useNuxtApp();
const route = useRoute();

const { data: article } = await useFetch(
  `${useRuntimeConfig().public.strapiUrl}/api/articles/${route.params.slug}?populate=*`
);

onMounted(() => {
  if (article.value && $fb) {
    $fb.track('ViewContent', {
      content_name: article.value.data.attributes.title,
      content_ids: [article.value.data.id],
      content_type: 'article',
    });
  }
});
</script>

Method 4: React SPA + Strapi

Installation

npm install react-facebook-pixel

Implementation

// src/pixel.js
import ReactPixel from 'react-facebook-pixel';

export const initPixel = () => {
  const options = {
    autoConfig: true,
    debug: false,
  };
  ReactPixel.init(process.env.REACT_APP_META_PIXEL_ID, options);
  ReactPixel.pageView();
};

export const trackEvent = (eventName, data) => {
  ReactPixel.track(eventName, data);
};

export const trackCustomEvent = (eventName, data) => {
  ReactPixel.trackCustom(eventName, data);
};
// src/App.js
import { useEffect } from 'react';
import { useLocation } from 'react-router-dom';
import { initPixel, trackEvent } from './pixel';

function App() {
  const location = useLocation();

  useEffect(() => {
    initPixel();
  }, []);

  useEffect(() => {
    trackEvent('PageView');
  }, [location]);

  return (
    <div className="App">
      {/* Your app content */}
    </div>
  );
}

export default App;

GTM provides easier management of Meta Pixel and other tags.

1. Install GTM

See Install Google Tag Manager for GTM installation.

2. Add Meta Pixel in GTM

Create Tag:

  • Type: Custom HTML
  • HTML: Paste Meta Pixel code
  • Trigger: All Pages
<!-- 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>

3. Create Event Tags

ViewContent Event:

  • Type: Custom HTML
  • HTML:
<script>
fbq('track', 'ViewContent', {
  content_name: {{DLV - Content Title}},
  content_category: {{DLV - Category Name}},
  content_ids: [{{DLV - Content ID}}],
  content_type: 'article'
});
</script>
  • Trigger: Custom Eventview_content

Standard Meta Pixel Events for Strapi Sites

ViewContent

Track when users view Strapi content:

window.fbq('track', 'ViewContent', {
  content_name: article.attributes.title,
  content_category: article.attributes.category?.data?.attributes?.name,
  content_ids: [article.id],
  content_type: 'article',
});

Track content searches:

window.fbq('track', 'Search', {
  search_string: searchQuery,
  content_category: 'articles',
});

Lead (Newsletter Signup)

Track form submissions:

window.fbq('track', 'Lead', {
  content_name: 'Newsletter Signup',
  content_category: 'newsletter',
});

CompleteRegistration

Track user registrations:

window.fbq('track', 'CompleteRegistration', {
  content_name: 'User Registration',
  status: 'completed',
});

Custom Events

Track custom interactions:

window.fbq('trackCustom', 'ArticleShare', {
  content_id: article.id,
  share_method: 'twitter',
});

window.fbq('trackCustom', 'DownloadResource', {
  resource_name: file.attributes.name,
  resource_type: file.attributes.ext,
});

Conversions API (Server-Side Tracking)

For more accurate tracking, implement Conversions API alongside browser pixel.

Next.js API Route Example

// app/api/track-conversion/route.ts
export async function POST(request: Request) {
  const { eventName, eventData, userData } = await request.json();

  const pixelId = process.env.META_PIXEL_ID!;
  const accessToken = process.env.META_ACCESS_TOKEN!;

  const response = await fetch(
    `https://graph.facebook.com/v18.0/${pixelId}/events`,
    {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        data: [
          {
            event_name: eventName,
            event_time: Math.floor(Date.now() / 1000),
            action_source: 'website',
            event_source_url: request.headers.get('referer'),
            user_data: {
              client_ip_address: request.headers.get('x-forwarded-for'),
              client_user_agent: request.headers.get('user-agent'),
              ...userData,
            },
            custom_data: eventData,
          },
        ],
        access_token: accessToken,
      }),
    }
  );

  const data = await response.json();
  return Response.json(data);
}

Client-Side Usage

// Track both browser and server-side
const trackConversion = async (eventName: string, eventData: any) => {
  // Browser pixel
  if (typeof window !== 'undefined' && window.fbq) {
    window.fbq('track', eventName, eventData);
  }

  // Server-side API
  await fetch('/api/track-conversion', {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      eventName,
      eventData,
      userData: {}, // Add hashed user data if available
    }),
  });
};

Environment Variables

# .env.local
NEXT_PUBLIC_META_PIXEL_ID=123456789012345
META_ACCESS_TOKEN=your_access_token_for_conversions_api

Testing Meta Pixel

1. Meta Pixel Helper

Install Meta Pixel Helper browser extension.

  • Green icon = Pixel working correctly
  • Shows events firing in real-time
  • Displays event parameters

2. Events Manager Test Events

In Meta Events Manager:

  • Go to Test Events
  • Enter your website URL
  • Navigate and trigger events
  • Verify events appear in real-time

3. Browser Console

// Check if pixel loaded
console.log(window.fbq);

// Manually fire test event
fbq('track', 'ViewContent', {
  content_name: 'Test',
  content_ids: ['123'],
  content_type: 'test',
});
// Wait for consent before initializing pixel
const initPixelWithConsent = () => {
  // Check consent (example using a consent library)
  if (userConsentedToMarketing) {
    window.fbq('init', PIXEL_ID);
    window.fbq('track', 'PageView');
  }
};

// Revoke consent
const revokePixelConsent = () => {
  if (window.fbq) {
    window.fbq('consent', 'revoke');
  }
};

// Grant consent
const grantPixelConsent = () => {
  if (window.fbq) {
    window.fbq('consent', 'grant');
  }
};

Common Issues

Pixel Not Loading

Cause: Ad blockers or incorrect pixel ID.

Solution:

  • Test in incognito mode
  • Verify pixel ID is correct
  • Check browser console for errors

Events Not Firing

Cause: SSR timing issues or missing window check.

Solution:

// Always check for window
if (typeof window !== 'undefined' && window.fbq) {
  window.fbq('track', 'ViewContent');
}

Duplicate Events

Cause: Multiple pixel implementations.

Solution:

  • Remove duplicate pixel code
  • Use GTM to manage pixel centrally
  • Check for pixel in multiple files

Next Steps

For general Meta Pixel concepts, see Meta Pixel Guide.