EventContext
EventContext is a small metadata object that the Funnel dispatcher
generates on every track() call and passes to
each plugin’s track(). It holds data
that is not part of the GA4 event schema but is needed for cross-platform features, chiefly
server-side deduplication.
import type { EventContext } from "@sunwjy/funnel-core";| Field | Type | Description |
|---|---|---|
eventId |
string |
Unique identifier for this event, used for deduplication (e.g., Meta CAPI). |
One eventId per track(), shared by every plugin
Section titled “One eventId per track(), shared by every plugin”For a single track() call, the dispatcher generates one eventId and hands the same
context object to every registered plugin. So GA4, the Meta Pixel, and any other plugin all see
the identical eventId for that one event.
This is the key to deduplication: if the same event is reported through two channels (for
example the Meta Pixel in the browser and the Meta Conversions API (CAPI) from your
server), both reports can carry the same eventId, and Meta will count it once instead of twice.
// Inside a plugin, the eventId is available on context:track(eventName, params, context) { fbq("track", "Purchase", { value: params.value }, { eventID: context.eventId });}How eventId is generated
Section titled “How eventId is generated”The dispatcher uses crypto.randomUUID() when it’s available (modern browsers and Node), and
falls back to a UUID-v4-shaped string built with Math.random() in environments that lack it.
Either way you get a unique UUID-shaped string.
The eventId is generated at call time. So if you track() before initialize(), the event
is queued and later replayed with its original eventId intact. The identity is fixed when
you call track, not when it is dispatched. See
queuing before initialize.
Powering server-side deduplication
Section titled “Powering server-side deduplication”The typical flow when you run a pixel in the browser and its server-side counterpart:
- The browser calls
funnel.track("purchase", { ... }). The dispatcher creates oneeventId. - The browser-side plugin (e.g., Meta Pixel) sends the event with that
eventId. - You forward the same logical event to the platform’s server API (e.g., Meta CAPI) with the
same
eventId. - The platform sees two reports of one event sharing an ID and deduplicates them.
To make step 3 possible, expose the eventId to your server (e.g., include it in the request
body when the browser also calls your backend). The shared identifier is what links the two
reports.
See also
Section titled “See also”Funnel: generates theEventContexton eachtrack().FunnelPlugin: receivescontextas the thirdtrackargument.EventMap: note thatpurchase.transaction_idis the GA4-level ID many platforms also use for purchase deduplication.