pixel: integrate conversion API

This commit is contained in:
Elijah Duffy
2025-12-18 17:12:57 -08:00
parent 824fd262ed
commit 9400e81aaa

View File

@@ -16,6 +16,12 @@ using the MetaPixel component.
* to prevent them from polluting real analytics data.
*/
testEventCode?: string;
/**
* if provided, all events fired will be passed to the server endpoint
* at this URL to be sent via the Conversion API. Any events sent
* without a event ID will be assigned a random one.
*/
conversionHref?: string;
/** Advanced matching data */
advancedMatching?: AdvancedMatching;
/** Initialization options */
@@ -26,6 +32,7 @@ using the MetaPixel component.
private _pixelID: string;
private _testEventCode?: string = undefined;
private _trackingManager: MaybeGetter<TrackingManager | undefined>;
private _conversionClient?: ConversionClient = undefined;
private static _baseLoaded: boolean = false;
private static _registeredPixels: Record<string, PixelControl> = {};
@@ -54,6 +61,18 @@ using the MetaPixel component.
this._trackingManager = trackingManager;
this._pixelID = pixelID;
this._testEventCode = options?.testEventCode;
const resolvedTrackingManager = resolveGetter(trackingManager);
if (options?.conversionHref && resolvedTrackingManager) {
this._conversionClient = new ConversionClient(
options.conversionHref,
resolvedTrackingManager
);
} else if (options?.conversionHref) {
log.warn(
`Conversion Client ${options.conversionHref} for Meta Pixel [${this._pixelID}] not initialized - TrackingManager is required for user consent.`
);
}
}
/** Loads the Meta Pixel base script. */
@@ -154,9 +173,34 @@ using the MetaPixel component.
*/
pageView() {
if (!this.consentGuard()) return;
// Send the PageView event
let eventID: string | undefined = undefined;
// Optionally, send to conversion API endpoint if configured
if (this._conversionClient) {
eventID = crypto.randomUUID();
this._conversionClient
.trackEvent('PageView', { eventID })
.then((response) => {
log.debug(
`Meta Pixel [${this._pixelID}] PageView event sent to Conversion API with Event ID: ${eventID}, Response: ${JSON.stringify(
response
)}`
);
})
.catch((error) => {
log.error(
`Meta Pixel [${this._pixelID}] Failed to send PageView event to Conversion API with Event ID: ${eventID}`,
error
);
});
}
// Send the PageView event to Meta
if (!dev || this._testEventCode) {
window.fbq('track', 'PageView', undefined, { test_event_code: this._testEventCode });
window.fbq('track', 'PageView', undefined, {
test_event_code: this._testEventCode,
eventID
});
log.debug(
`Meta Pixel [${this._pixelID}] PageView event sent${dev && ` (test code: ${this._testEventCode})`}.`
);
@@ -173,6 +217,28 @@ using the MetaPixel component.
*/
track<K extends StandardEventName>(event: K, params?: EventParamsByName[K], eventID?: string) {
if (!this.consentGuard()) return;
// Optionally, send to conversion API endpoint if configured
if (this._conversionClient) {
eventID = eventID ?? crypto.randomUUID();
this._conversionClient
.trackEvent(event, { eventID: eventID, customData: params as any })
.then((response) => {
log.debug(
`Meta Pixel [${this._pixelID}] ${event} event sent to Conversion API with Event ID: ${eventID}, Response: ${JSON.stringify(
response
)}`
);
})
.catch((error) => {
log.error(
`Meta Pixel [${this._pixelID}] Failed to send ${event} event to Conversion API with Event ID: ${eventID}`,
error
);
});
}
// Send the PageView event to Meta
if (!dev || this._testEventCode) {
window.fbq('trackSingle', this._pixelID, event, params, {
eventID,
@@ -228,6 +294,7 @@ using the MetaPixel component.
import { resolveGetter, type MaybeGetter } from './util/getter.ts';
import log from 'loglevel';
import { dev } from '$app/environment';
import { ConversionClient } from './conversion/client.ts';
interface Props {
/**