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.

npm@trackbridge/browser
1$ pnpm add @trackbridge/browser
2
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 key
14 userData,
15})

Quickstart

Same call, both sides.

Pass a shared transactionId. Google merges them. You write seven lines.

browserapp/checkout/success.tsx
1import { tracker } from "@/lib/tracker"
2
3await tracker.trackConversion({
4 label: "purchase",
5 value: order.total,
6 currency: "USD",
7 transactionId: order.id, // dedup key
8 userData,
9})
✗ may be blocked: adblock, ITP, consent
serverapi/webhooks/checkout.ts
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 → dedupes
8 gclid: order.gclid,
9 userData,
10})
✓ always reaches Google Ads API

Debug

Failures log to console.

Two warnings stay loud in production — the ones only you can fix. Your checkout never crashes.

consoleDevTools

[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.

start here

@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

shared

Transitive. 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.