meta pixel: default to disablePushState = true
Breaks SvelteKit SPA which doesn't allow use of history API, requiring its own wrapper to be used instead.
This commit is contained in:
5
src/lib/types/fbq.d.ts
vendored
5
src/lib/types/fbq.d.ts
vendored
@@ -340,6 +340,11 @@ export interface FBQ {
|
||||
// consent and LDU
|
||||
(cmd: 'consent', state: 'grant' | 'revoke'): void;
|
||||
(cmd: 'dataProcessingOptions', options: string[], countryCode?: number, stateCode?: number): void;
|
||||
|
||||
/** Prevent automatic listening to history.pushState/popstate */
|
||||
disablePushState?: boolean;
|
||||
/** Allow duplicate page view events (legacy / undocumented behavior) */
|
||||
allowDuplicatePageViews?: boolean;
|
||||
}
|
||||
|
||||
declare global {
|
||||
|
||||
@@ -9,22 +9,48 @@ type QueuedFBQ = ((...args: unknown[]) => void) & {
|
||||
loaded?: boolean;
|
||||
version?: string;
|
||||
push?: unknown;
|
||||
disablePushState?: boolean;
|
||||
allowDuplicatePageViews?: boolean;
|
||||
};
|
||||
|
||||
/**
|
||||
* Loads the Meta Pixel script and configures the `fbq` function to queue
|
||||
* commands until the script is fully loaded. You may optionally await the
|
||||
* returned Promise to ensure the script has loaded before proceeding.
|
||||
*
|
||||
* Options:
|
||||
* - `disablePushState` (default: true) — when true, sets
|
||||
* `window.fbq.disablePushState = true` before the pixel script loads so the
|
||||
* pixel does not auto-listen to `history.pushState`/`popstate` (recommended
|
||||
* for SPA frameworks like Svelte).
|
||||
* - `allowDuplicatePageViews` (default: false) — when true, sets
|
||||
* `window.fbq.allowDuplicatePageViews = true` on the stub.
|
||||
*/
|
||||
export const loadMetaPixel = (): Promise<void> => {
|
||||
export const loadMetaPixel = (opts?: {
|
||||
disablePushState?: boolean;
|
||||
allowDuplicatePageViews?: boolean;
|
||||
}): Promise<void> => {
|
||||
// Make sure we're using the browser
|
||||
if (!browser || !window) {
|
||||
return Promise.reject(new Error(`Not in browser, can't access window`));
|
||||
}
|
||||
|
||||
// Default behavior: disable pushState handling since Svelte apps manage
|
||||
// navigation themselves and Meta's auto-patching of history APIs can
|
||||
// cause duplicate/incorrect pageview events. Consumers can pass
|
||||
// `opts.disablePushState = false` to opt out.
|
||||
const disablePushState = opts?.disablePushState ?? true;
|
||||
const allowDuplicatePageViews = opts?.allowDuplicatePageViews ?? false;
|
||||
|
||||
// If fbq is already defined, resolve immediately
|
||||
const existing = window.fbq as QueuedFBQ | undefined;
|
||||
if (existing) {
|
||||
// If the existing stub is present but hasn't set these flags yet, set
|
||||
// them now so the loaded library (if it inspects them) sees intended
|
||||
// behavior. Setting these is a no-op if initialization already
|
||||
// completed.
|
||||
if (disablePushState) existing.disablePushState = true;
|
||||
if (allowDuplicatePageViews) existing.allowDuplicatePageViews = true;
|
||||
const existingScript = getExistingScript();
|
||||
if (existingScript) {
|
||||
return new Promise((resolve, reject) => {
|
||||
@@ -53,6 +79,9 @@ export const loadMetaPixel = (): Promise<void> => {
|
||||
q.push = q;
|
||||
q.loaded = true;
|
||||
q.version = '2.0';
|
||||
// set control flags on the stub before the meta script runs
|
||||
if (disablePushState) q.disablePushState = true;
|
||||
if (allowDuplicatePageViews) q.allowDuplicatePageViews = true;
|
||||
window.fbq = q;
|
||||
window._fbq = q;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user