Skip to content

createBrowserTracker()

The browser tracker. Captures Google Ads click identifiers from the URL on initialization, persists them to first-party cookies (gated on consent), and exposes methods to fire conversions and events through window.gtag.

import { createBrowserTracker } from '@trackbridge/sdk/browser';
function createBrowserTracker(config: BrowserTrackerConfig): BrowserTracker;
type BrowserTrackerConfig = {
adsConversionId: string;
ga4MeasurementId?: string;
/** Default: 'off'. */
consentMode?: 'v2' | 'off';
/** Default: 'cookie'. */
clickIdentifierStorage?: 'cookie' | 'memory' | 'none';
cookieDomain?: string;
/** Default: 90. */
cookieExpiryDays?: number;
debug?: boolean;
/** Default: false. When true, ?tb_debug=1 (or =0) overrides debug at init. */
debugUrlParam?: boolean;
io?: BrowserIO;
generateTransactionId?: () => string;
now?: () => number;
conversionLabels?: {
purchase?: string;
beginCheckout?: string;
addToCart?: string;
signUp?: string;
};
};
FieldRequiredNotes
adsConversionIdyesThe Google Ads property of the form AW-XXXXXXXXX. Used to construct send_to on every conversion event.
ga4MeasurementIdnoThe GA4 property of the form G-XXXXXXXXXX. Required if you’ll call tracker.trackEvent, the helpers, trackPageView, or identifyUser / clearUser.
consentModeno, default 'off'When 'v2', click-identifier cookies are gated on ad_storage consent. Pre-grant values are held in memory.
clickIdentifierStorageno, default 'cookie''cookie' persists across sessions; 'memory' lasts until tab close; 'none' discards captured values immediately.
cookieDomainnoOptional Domain= attribute for the _tb_* cookies — set to .example.com to share across subdomains.
cookieExpiryDaysno, default 90Lifetime of the _tb_* cookies.
debugno, default falseWhen true, gtag exceptions are surfaced via console.warn. The auto-transactionId warning fires regardless of this flag. Runtime-overridable via tracker.setDebug().
debugUrlParamno, default falseWhen true, createBrowserTracker reads ?tb_debug=1 (or =0) from the URL and uses it as the initial debug value for this tracker. Memory-only — does not persist across full page reloads.
ionoTest seam for DOM/cookie/gtag I/O. You’ll only set this in tests.
generateTransactionIdnoTest seam. Default: tb_${crypto.randomUUID()}.
nownoTest seam. Default: Date.now. Used by exportContext for createdAt.
conversionLabelsnoPer-helper Ads conversion labels. When a helper’s key is set, the helper fires both an Ads conversion (with this label) and a GA4 event. When absent, the helper fires GA4 only. refund is intentionally absent — Ads refund adjustments are out of scope in v1.
type BrowserTracker = {
// Read-only state
getClickIdentifiers(): ClickIdentifiers;
getClientId(): string | undefined;
getSessionId(): string | undefined;
getConsent(): ConsentState;
// Writes
updateConsent(update: ConsentUpdate): void;
identifyUser(userId: string): void;
clearUser(): void;
setDebug(enabled: boolean): void;
// Context envelope
exportContext(input?: ExportContextInput): TrackbridgeContext;
// Generic fires
trackEvent(input: BrowserEventInput): Promise<void>;
trackConversion(input: BrowserConversionInput): Promise<void>;
trackPageView(input?: BrowserPageViewInput): Promise<void>;
// Semantic helpers
trackPurchase(input: BrowserPurchaseInput): Promise<void>;
trackBeginCheckout(input?: BrowserBeginCheckoutInput): Promise<void>;
trackAddToCart(input?: BrowserAddToCartInput): Promise<void>;
trackSignUp(input?: BrowserSignUpInput): Promise<void>;
trackRefund(input: BrowserRefundInput): Promise<void>;
};

See:

  1. Reads window.location.search for gclid, gbraid, and wbraid.
  2. Reads document.cookie for the corresponding _tb_* cookies.
  3. Merges both sources — URL values win on conflict.
  4. If clickIdentifierStorage === 'cookie' and consentMode === 'off' (or ad_storage is already 'granted'), writes cookies for any captured values immediately.
  5. If clickIdentifierStorage === 'cookie' and consent is unknown or denied, holds the captured values in memory; they will be persisted later if updateConsent({ ad_storage: 'granted' }) is called.

Throws synchronously at init if adsConversionId is missing or empty:

Error: [trackbridge] adsConversionId is required

After initialization, the tracker never throws on network or gtag failures. Failures are reported via console.warn if debug: true.

lib/tracker.client.ts
import { createBrowserTracker } from '@trackbridge/sdk/browser';
export const tracker = createBrowserTracker({
adsConversionId: process.env.NEXT_PUBLIC_GOOGLE_ADS_CONVERSION_ID!,
ga4MeasurementId: process.env.NEXT_PUBLIC_GA4_MEASUREMENT_ID!,
consentMode: 'v2',
cookieDomain: '.example.com',
debug: process.env.NODE_ENV !== 'production',
});