SDK · v0.4 · MIT · TypeScript
Send Google Ads conversions twice.
TypeScript SDK that fires from browser and server, dedupes by transactionId, and hashes user data per Google's spec.
1$ pnpm add @trackbridge/browser2 3import { createBrowserTracker } from '@trackbridge/browser'4 5const tracker = createBrowserTracker({6 adsConversionId: 'AW-123456789',7})8 9await tracker.trackConversion({10 label: 'purchase',11 value: order.total,12 currency: 'USD',13 transactionId: order.id, // dedup key14 userData,15})Quickstart
Same call, both sides.
Pass a shared transactionId. Google merges them. You write seven lines.
1import { tracker } from "@/lib/tracker"2 3await tracker.trackConversion({4 label: "purchase",5 value: order.total,6 currency: "USD",7 transactionId: order.id, // dedup key8 userData,9})1import { serverTracker } from "@/lib/server"2 3await serverTracker.trackConversion({4 label: "purchase",5 value: order.total,6 currency: "USD",7 transactionId: order.id, // same key → dedupes8 gclid: order.gclid,9 userData,10})Debug
Failures log to console.
Two warnings stay loud in production — the ones only you can fix. Your checkout never crashes.
[trackbridge] ⚠ trackConversion called without transactionId
→ Auto-generated: tb_a8f3c1d2-4e7b-...
→ Dual-send disabled. Pass a transactionId you control.
fires in production · always[trackbridge] ⚠ Ads API → 401 Unauthorized
→ Refresh-token rejected. Check GOOGLE_ADS_REFRESH_TOKEN.
→ Conversion was NOT recorded. retry: false.
[trackbridge] ✓ purchase → $338.00 USD · tid ord_b7e0a3
hash: 8c2a…f704 · gclid present · ec_user_data: 3 fields normalized
Packages
Two to install.
@trackbridge/browser
client$ pnpm add @trackbridge/browser- createBrowserTracker · trackConversion · trackEvent
- Wraps gtag, pushes to dataLayer
- gclid / gbraid / wbraid auto-capture
- Consent Mode v2
@trackbridge/server
server$ pnpm add @trackbridge/server- createServerTracker · trackConversion · trackEvent
- Google Ads API: OAuth refresh-token flow
- GA4 Measurement Protocol
- Same hashing, byte-identical to browser
@trackbridge/core
sharedTransitive. Don't import directly.
- Normalization per Google's enhanced-conversion spec
- SHA-256 user-data hashing
- Email lowercase + trim + NFC
- Phone digits-only with leading +
Roadmap
Shipped, planned.
shipped
Google Ads enhanced conversions
Browser via gtag · server via Ads API.
GA4 events
Browser via gtag · server via Measurement Protocol.
Consent Mode v2
ad_storage gates cookie writes; deferred persistence.
Click identifier auto-capture
gclid / gbraid / wbraid · 90-day first-party cookies.
Debug mode
console.warn on failures.
planned
Cross-domain _gl linker
v1.1+.
Meta CAPI adapter
v1.1+.
TikTok Events API adapter
v1.1+.
Trackbridge Dashboard
Separate product, post-v1.