Code
Every file in a Transformation is an async function that receives a params object and returns an object describing what EdgeTag should do with the event. This page is the reference: what's in params for each file, what you can return, and what each return shape actually does.
You never write wrappers, imports, or exports — only the function body.
The return shape
Every file returns a plain object. Any combination of these fields is valid:
return {} // no-op (pass through)
return { payload } // modify the event
return { skipEvent: true } // drop the event
return { additionalEvents: [event1, ...] } // fan out extra events
return { user } // update user data (edge only)
return { payload, additionalEvents } // combine any of the aboveReturning nothing at all is equivalent to return {}.
tagRoot
tagRootRuns on the edge once per event, before any channel routing. Use for global rules — drop an event everywhere, enrich every payload, and emit an additional event based on attribution.
Available on params:
payload— the event:eventName,eventId,sdkVersion,locale,search,referrer,data(standard event fields).user— hashable PII (email,phone,firstName,lastName,zip, …), ornull.variables— your Secrets as a plain object.configuration— any configuration attached to the event.platform— e.g.SHOPIFY,CUSTOM.userCustomData— custom tags attached via the SDK.hostData— request metadata (userAgent,ip,country,city,region,timezone, …).logger.log(...),logger.error(...).userKey.getFirstClick(),userKey.getLastClick()— paid-media attribution helpers.providerData— raw click IDs and UTMs captured for this user.
tagChannel
tagChannelRuns on the edge once per provider channel. Same params as tagRoot, plus:
providerId— the channel being processed (e.g.'facebook','google','tiktok').
Use for provider-specific rules.
tagInstance
tagInstanceRuns on the edge once per provider instance (for example facebook||pixel1), the most granular edge level. Same params as tagChannel, including providerId. Use when you have multiple pixels or accounts inside a provider and need different behavior for each.
clientTagRoot
clientTagRootRuns in the browser once per event, before any provider tag fires.
Available on params:
payload—eventName,eventId,data.user— reserved for browser user data (currently empty).settings—userId,sessionId,geoCountry,geoRegion,isEURequest,ip,consent,consentCategories,userProperties.variables— only the Secrets you've flagged as client-side.
clientTagChannel / clientTagInstance
clientTagChannel / clientTagInstanceSame as clientTagRoot, plus providerId. Use these for browser-side provider- or instance-specific rules — for example, skipping a provider's browser pixel for EU traffic.
Paid-media helpers
Two helpers on edge params make paid-media attribution easy. Both are easy to misuse, so read carefully.
params.userKey.getFirstClick() and getLastClick()
Returns a provider ID string or null. The provider ID tells you which paid channel drove this user; it is not a click ID, a URL, or a query string.
Valid return values are literal strings from a fixed set: 'facebook', 'googleAdsClicks', 'bing', 'snapchat', 'tiktok', 'twitter', 'linkedIn', 'pinterest', 'reddit', 'appLovin', 'taboola', 'outbrain', 'trybe', or null.
params.providerData
The raw click IDs and UTM values captured for this user, keyed by provider and then by the original query-parameter name:
An empty providerData means no paid-media clicks or UTMs were ever captured for this user.
getFirstClick() and getLastClick() return a provider ID like 'facebook', not the fbclid. Don't try to parse it with new URL(...) or URLSearchParams — just compare it to a literal provider ID or to null.
What a Transformation can do
The four capabilities described at the top — modify, skip, fan out, update user — cover every real use case. Here's one real example of each.
Create new events
When a Purchase happens, and the user's first or last paid-media click was Facebook, fan out a second Purchase_Facebook event alongside the original. This is where userKey and additionalEvents work together.
additionalEvents is honored from tagRoot on the edge and clientTagRoot in the browser. Each additional event then goes through channel routing like any other event.
Combining capabilities
A single return can do more than one thing. This example enriches the payload and emits an additional event for Facebook-attributed purchases in the same call:
Return-value reference
payload
event object
Replace the event payload for this level.
user
user object or null
Replace user data for this level. Edge only.
additionalEvents
array of event objects
Emit extra events. Root-level only (tagRoot, clientTagRoot).
skipEvent
boolean
true drops the event at this level.
What's not available
Transformations are pure event transforms — by design, they don't:
make outbound HTTP requests (
requestHandleris not available)write to the identity graph (
userSave,userGet,providerSaveare not available)access storage bindings (
infrais not available)
If you need any of those, use a Destination.
Last updated
Was this helpful?

