meta pixel: more robust loading & graceful failure with adblockers

This commit is contained in:
Elijah Duffy
2025-12-16 21:04:32 -08:00
parent eeccb09b0b
commit bb92e25485
2 changed files with 45 additions and 17 deletions

View File

@@ -1,4 +1,5 @@
import { browser } from '$app/environment';
import log from 'loglevel';
const SCRIPT_SRC = 'https://connect.facebook.net/en_US/fbevents.js';
@@ -18,12 +19,24 @@ type QueuedFBQ = ((...args: unknown[]) => void) & {
export const loadMetaPixel = (): Promise<void> => {
// Make sure we're using the browser
if (!browser || !window) {
return Promise.reject(new Error('Window is undefined'));
return Promise.reject(new Error(`Not in browser, can't access window`));
}
// If fbq is already defined, resolve immediately
const existing = window.fbq as QueuedFBQ | undefined;
if (existing && existing.loaded) {
if (existing) {
const existingScript = getExistingScript();
if (existingScript) {
return new Promise((resolve, reject) => {
attachToScript(existingScript, resolve, reject);
});
}
log.debug(
'Meta Pixel fbq already present, skipping injection',
existing.version,
existing.queue
);
return Promise.resolve();
}
@@ -41,17 +54,14 @@ export const loadMetaPixel = (): Promise<void> => {
q.loaded = true;
q.version = '2.0';
window.fbq = q;
window._fbq = q;
return new Promise((resolve, reject) => {
// Avoid adding the same script twice
const existingScript = document.querySelector(
`script[src="${SCRIPT_SRC}"]`
) as HTMLScriptElement | null;
const existingScript = getExistingScript();
if (existingScript) {
existingScript.addEventListener('load', () => resolve());
existingScript.addEventListener('error', () =>
reject(new Error('Failed to load Meta Pixel script'))
);
attachToScript(existingScript, resolve, reject);
log.debug('Meta Pixel script already present, waiting for load');
return;
}
@@ -59,8 +69,23 @@ export const loadMetaPixel = (): Promise<void> => {
const script = document.createElement('script');
script.src = SCRIPT_SRC;
script.async = true;
script.addEventListener('load', () => resolve());
script.addEventListener('error', () => reject(new Error('Failed to load Meta Pixel script')));
attachToScript(script, resolve, reject);
document.head.appendChild(script);
log.debug('Meta Pixel script added to document');
});
};
const getExistingScript = (): HTMLScriptElement | null => {
return document.querySelector(
`script[src*="connect.facebook.net"][src*="fbevents.js"]`
) as HTMLScriptElement | null;
};
const attachToScript = (
el: HTMLScriptElement,
resolve: () => void,
reject: (err: Error) => void
) => {
el.addEventListener('load', () => resolve());
el.addEventListener('error', () => reject(new Error('Failed to load Meta Pixel script')));
};