-
Notifications
You must be signed in to change notification settings - Fork 0
feat(components): add MetaPixel component with event tracking #5
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,111 @@ | ||
| 'use client' | ||
|
|
||
| import Script from 'next/script' | ||
|
|
||
| export interface MetaPixelProps { | ||
| /** Meta (Facebook) Pixel ID (e.g., '1234567890123456') */ | ||
| pixelId: string | ||
| /** Load strategy (default: 'afterInteractive') */ | ||
| strategy?: 'afterInteractive' | 'lazyOnload' | 'beforeInteractive' | ||
| /** Disable automatic PageView tracking (default: false) */ | ||
| disablePageView?: boolean | ||
| } | ||
|
|
||
| const PIXEL_ID_PATTERN = /^\d{15,16}$/ | ||
|
|
||
| export function MetaPixel({ | ||
| pixelId, | ||
| strategy = 'afterInteractive', | ||
| disablePageView = false | ||
| }: MetaPixelProps) { | ||
| // Don't render if no pixel ID or invalid format | ||
| if (!pixelId || !PIXEL_ID_PATTERN.test(pixelId)) { | ||
| return null | ||
| } | ||
|
|
||
| const pageViewScript = disablePageView ? '' : `fbq('track', 'PageView');` | ||
|
|
||
| return ( | ||
| <> | ||
| <Script id="meta-pixel-init" strategy={strategy}> | ||
| {` | ||
| !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}'); | ||
| ${pageViewScript} | ||
| `} | ||
| </Script> | ||
| {!disablePageView && ( | ||
| <noscript> | ||
| <img | ||
| height="1" | ||
| width="1" | ||
| style={{ display: 'none' }} | ||
| src={`https://www.facebook.com/tr?id=${pixelId}&ev=PageView&noscript=1`} | ||
| alt="" | ||
| /> | ||
| </noscript> | ||
| )} | ||
| </> | ||
| ) | ||
| } | ||
|
|
||
| /** | ||
| * Track a standard Meta Pixel event | ||
| * Use this for Facebook's predefined standard events | ||
| * | ||
| * @see https://developers.facebook.com/docs/meta-pixel/reference#standard-events | ||
| * | ||
| * @example | ||
| * trackMetaEvent('Lead') | ||
| * trackMetaEvent('Purchase', { value: 99.99, currency: 'USD' }) | ||
| * trackMetaEvent('AddToCart', { content_ids: ['SKU123'], value: 29.99 }) | ||
| */ | ||
| export function trackMetaEvent( | ||
| eventName: string, | ||
| params?: Record<string, unknown> | ||
| ) { | ||
| if (typeof window !== 'undefined' && typeof window.fbq === 'function') { | ||
| window.fbq('track', eventName, params) | ||
| } | ||
| } | ||
|
|
||
| /** | ||
| * Track a custom Meta Pixel event | ||
| * Use this for your own custom events (not Facebook's standard events) | ||
| * | ||
| * @see https://developers.facebook.com/docs/meta-pixel/reference#custom-events | ||
| * | ||
| * @example | ||
| * trackMetaCustomEvent('StartTrial') | ||
| * trackMetaCustomEvent('ShareContent', { content_type: 'article' }) | ||
| */ | ||
| export function trackMetaCustomEvent( | ||
| eventName: string, | ||
| params?: Record<string, unknown> | ||
| ) { | ||
| if (typeof window !== 'undefined' && typeof window.fbq === 'function') { | ||
| window.fbq('trackCustom', eventName, params) | ||
| } | ||
| } | ||
|
Comment on lines
+70
to
+96
|
||
|
|
||
| // Extend Window interface for TypeScript | ||
| declare global { | ||
| interface Window { | ||
| fbq: { | ||
| (action: 'init', pixelId: string, options?: Record<string, unknown>): void | ||
| ( | ||
| action: 'track' | 'trackCustom', | ||
| eventName: string, | ||
| params?: Record<string, unknown> | ||
| ): void | ||
| (action: string, ...args: unknown[]): void | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,3 +1,4 @@ | ||
| export * from './BasicPageLayout' | ||
| export * from './GoogleAnalytics' | ||
| export * from './MetaPixel' | ||
| export * from './ScrollToTop' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The documentation comment states this function can be used for custom events (line 66-67), but the implementation only uses fbq('track', ...) which is for standard events. Custom events in Facebook Pixel should use fbq('trackCustom', eventName, params). This could lead to confusion or incorrect event tracking. Consider either updating the implementation to handle custom events differently or clarifying in the documentation that this function is for standard events only.