diff --git a/src/lib/MetaPixel.svelte b/src/lib/MetaPixel.svelte
new file mode 100644
index 0000000..4326498
--- /dev/null
+++ b/src/lib/MetaPixel.svelte
@@ -0,0 +1,190 @@
+
+
+
diff --git a/src/lib/types/fbq.d.ts b/src/lib/types/fbq.d.ts
new file mode 100644
index 0000000..01bb570
--- /dev/null
+++ b/src/lib/types/fbq.d.ts
@@ -0,0 +1,351 @@
+/**
+ * Meta Pixel (fbq) Type Definitions
+ *
+ * This file contains strongly-typed definitions for the Meta Pixel global
+ * (`fbq`) and its standard event parameter shapes. Exported types cover
+ * per-event params (e.g., `PurchaseParams`), the `FBQ` callable interface,
+ * `AdvancedMatching` for `fbq('init', ...)`, and related helper types.
+ *
+ * Example:
+ * ```ts
+ * import type { FBQ, PurchaseParams } from '$lib/types/fbq';
+ * // call the global pixel (browser only)
+ * window.fbq('track', 'Purchase', { currency: 'USD', value: 9.99 } as PurchaseParams);
+ * ```
+ */
+
+/** A Meta Pixel identifier string. */
+export type PixelId = string;
+
+/**
+ * Optional fourth argument for deduplication when sending events to Conversions
+ * API and test events.
+ */
+export type EventOptions = {
+ eventID?: string;
+ test_event_code?: string;
+};
+
+/**
+ * Common event parameter values shared across many standard events.
+ * Use `EventParamsByName` to map specific standard events to their params.
+ */
+export type CommonParams = Partial<{
+ /**
+ * Category of the page/product.
+ */
+ content_category: string;
+
+ /**
+ * Product IDs associated with the event, such as SKUs (e.g. ["ABC123", "XYZ456"]).
+ */
+ content_ids: (string | number)[];
+
+ /**
+ * Name of the page/product.
+ */
+ content_name: string;
+
+ /**
+ * Type of content referenced in `content_ids`. If IDs refer to individual
+ * products, use 'product'. If they refer to groups of products, use 'product_group'.
+ *
+ * If empty, Meta will match the event to every item that has the same ID,
+ * independent of its type.
+ */
+ content_type: 'product' | 'product_group';
+
+ /**
+ * Array of JSON objects that contains the quantity and the International
+ * Article Number (EAN) when applicable, or other product or content identifiers.
+ *
+ * Custom parameters can also be included in each object.
+ */
+ contents: { id: string | number; quantity: number }[];
+
+ /**
+ * The currency for the `value` specified.
+ */
+ currency: string;
+
+ /**
+ * The number of items when checkout was initiated (used with `InitiateCheckout` event).
+ */
+ num_items: number;
+
+ /**
+ * Predicted lifetime value of a subscriber as defined by the advertiser
+ * and expressed as an exact value.
+ */
+ predicted_ltv: number;
+
+ /**
+ * Search string used in a search event (used with `Search` event).
+ */
+ search_string: string;
+
+ /**
+ * Shows status of a registration (used with `CompleteRegistration` event).
+ */
+ status: boolean;
+
+ /**
+ * The value of a user performing this event to the business.
+ */
+ value: number;
+}>;
+
+/**
+ * When payment information is added in the checkout flow.
+ */
+export type AddPaymentInfoParams = Partial<
+ Pick
+>;
+
+/**
+ * When a product is added to the shopping cart.
+ */
+export type AddToCartParams = Partial<
+ Pick
+>;
+
+/**
+ * When a product is added to a wishlist.
+ */
+export type AddToWishlistParams = Partial<
+ Pick
+>;
+
+/**
+ * When a registration form is completed.
+ */
+export type CompleteRegistrationParams = Partial> & {
+ status?: boolean;
+};
+
+/**
+ * When a person initiates contact with your business.
+ */
+export type ContactParams = Partial;
+
+/**
+ * When a person customizes a product.
+ */
+export type CustomizeProductParams = Partial;
+
+/**
+ * When a person donates funds to your organization or cause.
+ */
+export type DonateParams = Partial;
+
+/**
+ * When a person searched for a location of your store via a website or app,
+ * with an intention to visit the physical location.
+ */
+export type FindLocationParams = Partial;
+
+/**
+ * When a person enters the checkout flow prior to completing a purchase.
+ */
+export type InitiateCheckoutParams = Partial<
+ Pick
+>;
+
+/**
+ * When a sign up is completed.
+ */
+export type LeadParams = Partial>;
+
+/**
+ * When a purchase is made or checkout flow is completed.
+ */
+export type PurchaseParams = {
+ currency: string;
+ value: number;
+} & Partial>;
+
+/**
+ * When a person books an appointment to visit one of your locations.
+ */
+export type ScheduleParams = Partial;
+
+/**
+ * When a search is made.
+ */
+export type SearchParams = Partial<
+ Pick<
+ CommonParams,
+ 'content_ids' | 'content_type' | 'contents' | 'currency' | 'value' | 'search_string'
+ >
+>;
+
+/**
+ * When a person starts a free trial of a product or service you offer.
+ */
+export type StartTrialParams = Partial>;
+
+/**
+ * When a person applies for a product, service, or program you offer.
+ */
+export type SubmitApplicationParams = Partial;
+
+/**
+ * When a person subscribes to a paid product or service you offer.
+ */
+export type SubscribeParams = Partial>;
+
+/**
+ * A visit to a web page you care about (for example, a product page or landing page).
+ */
+export type ViewContentParams = Partial<
+ Pick
+>;
+
+/** Standard event names supported by Meta Pixel. */
+export type StandardEventName =
+ | 'AddPaymentInfo'
+ | 'AddToCart'
+ | 'AddToWishlist'
+ | 'CompleteRegistration'
+ | 'Contact'
+ | 'CustomizeProduct'
+ | 'Donate'
+ | 'FindLocation'
+ | 'InitiateCheckout'
+ | 'Lead'
+ | 'Purchase'
+ | 'Schedule'
+ | 'Search'
+ | 'StartTrial'
+ | 'SubmitApplication'
+ | 'Subscribe'
+ | 'ViewContent'
+ | 'PageView';
+
+/**
+ * Advanced matching fields accepted by the Pixel init call. These fields are
+ * used to help match site visitors to people on Meta for better attribution.
+ * See Meta's Advanced Matching docs for details; values should generally be
+ * raw strings (or hashed values if you pre-hash on the client/server).
+ */
+export type AdvancedMatching = {
+ /** Primary contact email (or hashed email) */
+ email?: string;
+ /** Phone number (E.164 or local) */
+ phone?: string;
+ /** First name */
+ first_name?: string;
+ /** Last name */
+ last_name?: string;
+ /** City */
+ city?: string;
+ /** State/region */
+ state?: string;
+ /** Postal / ZIP code */
+ zip?: string;
+ /** Country code */
+ country?: string;
+ /** External id to match users (optional) */
+ external_id?: string;
+ /** Gender */
+ gender?: string;
+ /** Date of birth (ISO-like or YYYY-MM-DD) */
+ date_of_birth?: string;
+ // allow additional provider-specific keys
+ [key: string]: string | undefined;
+};
+
+/** Arbitrary init/config options from the global pixel initialization API. */
+export type InitOptions = Record;
+
+/** Additional custom params for custom events. */
+export type CustomParams = Record;
+
+/** Map each standard event name to its allowed parameter shape. */
+export type EventParamsByName = {
+ AddPaymentInfo: AddPaymentInfoParams;
+ AddToCart: AddToCartParams;
+ AddToWishlist: AddToWishlistParams;
+ CompleteRegistration: CompleteRegistrationParams;
+ Contact: ContactParams;
+ CustomizeProduct: CustomizeProductParams;
+ Donate: DonateParams;
+ FindLocation: FindLocationParams;
+ InitiateCheckout: InitiateCheckoutParams;
+ Lead: LeadParams;
+ Purchase: PurchaseParams;
+ Schedule: ScheduleParams;
+ Search: SearchParams;
+ StartTrial: StartTrialParams;
+ SubmitApplication: SubmitApplicationParams;
+ Subscribe: SubscribeParams;
+ ViewContent: ViewContentParams;
+ PageView: Record;
+};
+
+/** Strongly-typed interface for the `fbq` global provided by Meta Pixel. */
+export interface FBQ {
+ /**
+ * Initialize a pixel for this page.
+ * @param pixelId The pixel identifier to initialize.
+ * @param advancedMatching Optional advanced matching data (email/phone/etc.).
+ * @param options Additional init options.
+ */
+ (cmd: 'init', pixelId: PixelId, advancedMatching?: AdvancedMatching, options?: InitOptions): void;
+
+ // Strongly-typed track overloads.
+ (cmd: 'track', event: 'Purchase', params: PurchaseParams, options?: EventOptions): void;
+ /** Generic overload for other standard events where params are optional */
+ >(
+ cmd: 'track',
+ event: K,
+ params?: EventParamsByName[K],
+ options?: EventOptions
+ ): void;
+
+ /** Custom event variant — accepts arbitrary custom keys in addition to `CommonParams`. */
+ (
+ cmd: 'trackCustom',
+ event: string,
+ params?: CommonParams & CustomParams,
+ options?: EventOptions
+ ): void;
+
+ /** Single-pixel variants that mirror the typed `track` API without duplicating event shapes. */
+ (
+ cmd: 'trackSingle',
+ pixelId: PixelId,
+ event: K,
+ params?: EventParamsByName[K],
+ options?: EventOptions
+ ): void;
+ (
+ cmd: 'trackSingleCustom',
+ pixelId: PixelId,
+ event: string,
+ params?: CommonParams & CustomParams,
+ options?: EventOptions
+ ): void;
+
+ // Configuration helpers with typed keys and values.
+ (cmd: 'set', key: 'autoConfig', value: boolean, pixelId?: PixelId): void;
+ (
+ cmd: 'set',
+ key: 'test_event_code' | 'agent' | 'eventSourceUrl',
+ value: string,
+ pixelId?: PixelId
+ ): void;
+ (cmd: 'set', config: Record): void;
+
+ // consent and LDU
+ (cmd: 'consent', state: 'grant' | 'revoke'): void;
+ (cmd: 'dataProcessingOptions', options: string[], countryCode?: number, stateCode?: number): void;
+}
+
+declare global {
+ interface Window {
+ fbq: FBQ;
+ _fbq?: FBQ;
+ }
+}
+export {};
diff --git a/src/lib/util/getter.ts b/src/lib/util/getter.ts
new file mode 100644
index 0000000..a259fb5
--- /dev/null
+++ b/src/lib/util/getter.ts
@@ -0,0 +1,17 @@
+/**
+ * MaybeGetter is a type that can either be a value of type T or a function that returns a value of type T.
+ * This is useful for cases where you might want to pass a value directly or a function that computes the
+ * value later, potentially taking advantage of reactivity.
+ */
+export type MaybeGetter = T | (() => T);
+
+/**
+ * ResolveGetter returns the underlying value stored by a MaybeGetter type.
+ * @returns Raw value T or function return T.
+ */
+export const resolveGetter = (getter: MaybeGetter): T => {
+ if (typeof getter === 'function') {
+ return (getter as () => T)();
+ }
+ return getter;
+};
diff --git a/src/lib/util/meta-pixel-loader.ts b/src/lib/util/meta-pixel-loader.ts
new file mode 100644
index 0000000..c5485de
--- /dev/null
+++ b/src/lib/util/meta-pixel-loader.ts
@@ -0,0 +1,66 @@
+import { browser } from '$app/environment';
+
+const SCRIPT_SRC = 'https://connect.facebook.net/en_US/fbevents.js';
+
+type QueuedFBQ = ((...args: unknown[]) => void) & {
+ queue?: unknown[][];
+ callMethod?: (...args: unknown[]) => void;
+ loaded?: boolean;
+ version?: string;
+ push?: unknown;
+};
+
+/**
+ * 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.
+ */
+export const loadMetaPixel = (): Promise => {
+ // Make sure we're using the browser
+ if (!browser || !window) {
+ return Promise.reject(new Error('Window is undefined'));
+ }
+
+ // If fbq is already defined, resolve immediately
+ const existing = window.fbq as QueuedFBQ | undefined;
+ if (existing && existing.loaded) {
+ return Promise.resolve();
+ }
+
+ // Configure fbq to queue commands until Meta takes over
+ const q = function (...args: unknown[]) {
+ if (q.callMethod) {
+ q.callMethod(...args);
+ } else {
+ if (!q.queue) q.queue = [];
+ q.queue.push(args);
+ }
+ } as QueuedFBQ;
+ q.queue = [];
+ q.push = q;
+ q.loaded = true;
+ q.version = '2.0';
+ 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;
+ if (existingScript) {
+ existingScript.addEventListener('load', () => resolve());
+ existingScript.addEventListener('error', () =>
+ reject(new Error('Failed to load Meta Pixel script'))
+ );
+ return;
+ }
+
+ // Otherwise, create the script element
+ 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')));
+ document.head.appendChild(script);
+ });
+};