serverTracker.fromContext()
Hydrates a TrackbridgeContext envelope (typically produced by tracker.exportContext() on the browser) into a tracker bound to its identifiers, consent, and PII. The bound tracker exposes the same call surface as the unbound one — trackEvent, trackConversion, plus the five helpers — with envelope-derived fields filled in by default.
For the why and the end-to-end pattern, see The context envelope.
Signature
Section titled “Signature”serverTracker.fromContext(envelope: TrackbridgeContext): ContextBoundServerTracker;ContextBoundServerTracker
Section titled “ContextBoundServerTracker”type ContextBoundServerTracker = { trackEvent(input: BoundServerEventInput): Promise<ServerEventResult>; trackConversion(input: BoundServerConversionInput): Promise<ServerConversionResult>; trackPurchase(input: BoundPurchaseInput): Promise<ServerHelperResult>; trackBeginCheckout(input?: BoundBeginCheckoutInput): Promise<ServerHelperResult>; trackAddToCart(input?: BoundAddToCartInput): Promise<ServerHelperResult>; trackSignUp(input?: BoundSignUpInput): Promise<ServerHelperResult>; trackRefund(input: BoundRefundInput): Promise<ServerHelperResult>;};The Bound*Input types are the same as the unbound input types with clientId made optional. The bound tracker fills in clientId from envelope.clientId when omitted.
Field merge rules
Section titled “Field merge rules”For each call on the bound tracker:
clientId: per-call value wins, otherwiseenvelope.clientId. If neither supplies one, the call throws synchronously.gclid,gbraid,wbraid: per-call value wins per field. Envelope values fill in the rest.userId: per-call value wins, otherwiseenvelope.userId.userData: per-call value replacesenvelope.userDataentirely. There is no deep merge — partial overrides require the caller to spread.consent: per-call value wins. The envelope’sconsentsnapshot is treated asServerConsentdefaults.- All other fields (
transactionId,value,currency,items, etc.) come exclusively from the per-call input.
Errors
Section titled “Errors”Throws synchronously if the envelope is malformed:
- Unknown
v(currently anything other than1). - Missing
clickIdsorconsent. - Other shape violations.
These are programming errors, not runtime issues — envelopes are opaque payloads, not user-editable.
Example
Section titled “Example”import { serverTracker } from '@/lib/tracker.server';
export async function POST(req: Request) { const event = await verifyStripeSignature(req); if (event.type !== 'checkout.session.completed') return new Response();
const order = await db.orders.findByStripeId(event.data.object.id); const bound = serverTracker.fromContext(order.trackbridgeContext);
const result = await bound.trackPurchase({ transactionId: order.id, value: order.total, currency: order.currency, items: order.items, // clientId, gclid, userData all default from the envelope });
if (!result.ads.ok && !('skipped' in result.ads)) reportError(result.ads.error); return new Response();}To override one field of userData without losing the rest, spread:
await bound.trackPurchase({ transactionId: order.id, value: order.total, currency: order.currency, items: order.items, userData: { ...order.trackbridgeContext.userData, email: order.customer.updatedEmail, // overrides only the email },});See also
Section titled “See also”- The context envelope — concept overview.
tracker.exportContext()— the matching producer.TrackbridgeContext— the type.