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
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)
Choose Your Implementation Method
- Direct pixel code in frontend framework
- Google Tag Manager (recommended)
- Third-party libraries (react-facebook-pixel, etc.)
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;
Method 5: Google Tag Manager (Recommended)
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 Event →
view_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',
});
Search
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',
});
Privacy & Consent
Implement Consent Management
// 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
- GA4 Setup - Install Google Analytics
- GTM Setup - Use GTM for easier management
- Troubleshoot Events - Debug tracking issues
For general Meta Pixel concepts, see Meta Pixel Guide.