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
|
// consent and LDU
|
||||||
(cmd: 'consent', state: 'grant' | 'revoke'): void;
|
(cmd: 'consent', state: 'grant' | 'revoke'): void;
|
||||||
(cmd: 'dataProcessingOptions', options: string[], countryCode?: number, stateCode?: number): 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 {
|
declare global {
|
||||||
|
|||||||
@@ -9,22 +9,48 @@ type QueuedFBQ = ((...args: unknown[]) => void) & {
|
|||||||
loaded?: boolean;
|
loaded?: boolean;
|
||||||
version?: string;
|
version?: string;
|
||||||
push?: unknown;
|
push?: unknown;
|
||||||
|
disablePushState?: boolean;
|
||||||
|
allowDuplicatePageViews?: boolean;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the Meta Pixel script and configures the `fbq` function to queue
|
* Loads the Meta Pixel script and configures the `fbq` function to queue
|
||||||
* commands until the script is fully loaded. You may optionally await the
|
* commands until the script is fully loaded. You may optionally await the
|
||||||
* returned Promise to ensure the script has loaded before proceeding.
|
* 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
|
// Make sure we're using the browser
|
||||||
if (!browser || !window) {
|
if (!browser || !window) {
|
||||||
return Promise.reject(new Error(`Not in browser, can't access 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
|
// If fbq is already defined, resolve immediately
|
||||||
const existing = window.fbq as QueuedFBQ | undefined;
|
const existing = window.fbq as QueuedFBQ | undefined;
|
||||||
if (existing) {
|
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();
|
const existingScript = getExistingScript();
|
||||||
if (existingScript) {
|
if (existingScript) {
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
@@ -53,6 +79,9 @@ export const loadMetaPixel = (): Promise<void> => {
|
|||||||
q.push = q;
|
q.push = q;
|
||||||
q.loaded = true;
|
q.loaded = true;
|
||||||
q.version = '2.0';
|
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;
|
||||||
window._fbq = q;
|
window._fbq = q;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user