Reputation: 489
I know this may be a dumb question. How can I do to use facebook pixel on a next.js react app ?
Upvotes: 35
Views: 63775
Reputation: 167
I used dynamic
with SSR false to export the client component so you can use it with react-facebook-pixel
as usual.
The MetaPixelLazy.tsx
to be used in nextjs
import dynamic from 'next/dynamic'
export const MetaPixel = dynamic(() => import('./MetaPixel'), {
ssr: false,
})
Is importing the MetaPixel.tsx
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import ReactPixel from 'react-facebook-pixel'
interface MetaPixelProps {
pixelId: string
}
// this can't be instatiated in the server
export default function MetaPixelClient(p: MetaPixelProps) {
const { events } = useRouter()
useEffect(() => {
const checkPage = () => ReactPixel.pageView()
ReactPixel.init(p.pixelId)
checkPage()
events.on('routeChangeComplete', checkPage)
return () => {
events.off('routeChangeComplete', checkPage)
}
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [])
return null
}
Then I instantiate it inside the _app.tsx
and it will not break.
Upvotes: 1
Reputation: 51
For Next Js App Router:
Path: src/app/layout.jsx
export default function RootLayout({ children }) {
return (
<html lang='en' suppressHydrationWarning>
<Script id='fb-pixel' strategy='afterInteractive'>
{`
!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', '${process.env.FACEBOOK_PIXEL_ID}');
fbq('track', 'PageView');
`}
</Script>
<body className={openSans.className}>
<noscript>
<img
height='1'
width='1'
style='display:none'
alt={'facebook pixel no script image'}
src='https://www.facebook.com/tr?id=1002246091049642&ev=PageView&noscript=1'
/>
</noscript>
</body>
</html>
)
}
Upvotes: 5
Reputation: 7210
Use the new Script component released in Next.js version 11. Import the below into your _app.js
.
import { useEffect } from 'react'
import { useRouter } from 'next/router'
import {pageview, FB_PIXEL_ID} from '../../lib/fpixel'
import Script from 'next/script'
const handleRouteChange = () => {
pageview()
}
const FB_PIXEL_ID = process.env.NEXT_PUBLIC_FACEBOOK_PIXEL_ID
const pageview = () => {
window.fbq('track', 'PageView')
}
const FacebookPixel = ({ children }) => {
const router = useRouter()
useEffect(() => {
// the below will only fire on route changes (not initial load - that is handled in the script below)
router.events.on('routeChangeComplete', handleRouteChange)
return () => {
router.events.off('routeChangeComplete', handleRouteChange)
}
}, [router.events])
return (
<Script id="facebook-pixel">
{`
!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', ${FB_PIXEL_ID});
fbq('track', 'PageView');
`}
</Script>
)
}
export default FacebookPixel
Do not use strategy="lazyOnload"
. I was previously using this and the script was more likely to be blocked by adblocker if using this method.
Upvotes: 14
Reputation: 10183
Solution with typescript and hook with NextJs
yarn add react-facebook-pixel
_app.tsx
// pages/_app.tsx
import { useEffect } from 'react'
import { useRouter } from 'next/router'
const App = ({ Component, pageProps }) => {
const router = useRouter()
useEffect(() => {
import('react-facebook-pixel')
.then((x) => x.default)
.then((ReactPixel) => {
ReactPixel.init('XXXXXXXXXXXXXXXXXXXXX') // facebookPixelId
ReactPixel.pageView()
router.events.on('routeChangeComplete', () => {
ReactPixel.pageView()
})
})
}, [router.events])
return <Component {...pageProps} />
}
export default App
Remark: it works with typescript or JavaScript
Upvotes: 25
Reputation: 652
Simple and easy:
Put the below code inside _app.js
:
useEffect(async () => {
const { default: ReactPixel } = await import('react-facebook-pixel');
ReactPixel.init(FB_PIXEL, null, {
autoConfig: true,
debug: true,
});
ReactPixel.pageView();
ReactPixel.track("ViewContent")
});
Upvotes: 5
Reputation: 863
there are no dumb questions.
You can see nextjs example about how implements fb pixel. Nextjs Facebook Pixel
Upvotes: 54
Reputation: 2368
There's a library for React called react-facebook-pixel
. In order to make it work with NextJs, try this solution in your _app.jsx file:
function FacebookPixel() {
React.useEffect(() => {
import("react-facebook-pixel")
.then((x) => x.default)
.then((ReactPixel) => {
ReactPixel.init('pixel ID here');
ReactPixel.pageView();
Router.events.on("routeChangeComplete", () => {
ReactPixel.pageView();
});
});
});
return null;
}
export default function App({ Component, pageProps }) {
return (
<>
<Head>
<meta charSet="UTF-8" />
<meta
name="viewport"
content="width=device-width, initial-scale=1, viewport-fit=cover"
/>
</Head>
<FacebookPixel />
//…
<main className="routesContainer">
<Component siteData={siteData} {...pageProps} />
</main>
//…
</>
);
}
or in case you're using Class components, insert this in you componentDidMount() inside the App class:
componentDidMount() {
import('react-facebook-pixel')
.then((x) => x.default)
.then((ReactPixel) => {
ReactPixel.init('Pixel ID Here');
ReactPixel.pageView();
Router.events.on('routeChangeComplete', () => {
ReactPixel.pageView();
});
});
}
font: https://github.com/zsajjad/react-facebook-pixel/issues/53
Upvotes: 5