typed sdk

The TracerKit SDK

@tracerkit/js and @tracerkit/react — typed wrappers over window.tracerkitLayerand the loader API. Integrate with autocomplete instead of copy-pasted snippets. Zero runtime dependencies; every call is SSR-safe and no-ops when the loader isn't present.

Install
Publishing to npm is a manual ops step — the packages are ready-to-publish from packages/sdk-js and packages/sdk-react in the TracerKit repo. Until they land on the registry, install from a checkout (npm install <path>) or keep using the plain snippets.
npm install @tracerkit/js        # framework-agnostic core
npm install @tracerkit/react     # React/Next component + hook (includes the core)
@tracerkit/js
The framework-agnostic core. Types mirror the data layer spec field-for-field.
FunctionReturnsNotes
pushEvent(name, opts?)voidPushes { event: name, ...opts } onto window.tracerkitLayer. name autocompletes the five canonical events (page_view, view_item, add_to_cart, begin_checkout, purchase) and accepts any custom-trigger name. opts: { value?, currency?, items?, page_location?, page_title? } — extra fields pass through (the spec ignores unknown fields).
pushPurchase({ order_id, value, currency, items, email?, phone? })voidThe purchase event, typed field-for-field from the data layer spec. Push exactly once per order — TracerKit dedupes on order_id. email/phone are optional enhanced-matching fields, hashed in-browser by the loader.
identify({ email?, phone? })voidEnhanced matching. Values are hashed in-browser (SHA-256) by the loader — raw values never leave the page. Works before the loader boots (queued on the layer).
consent(state)voidSame contract as tracerkit.consent(): TracerKit categories ({ analytics, marketing }) or GCMv2 signal names ({ ad_storage, analytics_storage, ad_user_data, ad_personalization }), booleans or "granted"/"denied". Loader present → forwarded to tracerkit.consent() (blocked tags replay). Before the loader boots → normalized onto window.__tkConsent, the preset the loader applies on boot.
lastEventId()string | undefinedThe loader's per-fire event id. Pass it to a browser pixel (fbq eventID / ttq event_id) so the platform dedupes pixel + server into one conversion. undefined until the loader has fired an event.
import {
  pushEvent,
  pushPurchase,
  identify,
  consent,
} from "@tracerkit/js";

// funnel events — typed to the data layer spec
pushEvent("add_to_cart", {
  value: 79.98,
  currency: "USD",
  items: [{ id: "SKU-123", name: "Canvas Tote", price: 39.99, quantity: 2 }],
});

// exactly once per order, on the confirmation page
pushPurchase({
  order_id: "1001",
  value: 129.97,
  currency: "USD",
  items: [
    { id: "SKU-123", name: "Canvas Tote", price: 39.99, quantity: 2 },
    { id: "SKU-456", name: "Wool Beanie", price: 49.99, quantity: 1 },
  ],
  email: "jane@example.com", // optional — hashed in-browser
});

// enhanced matching outside of purchase (e.g. after login)
identify({ email: "jane@example.com" });

// consent — categories or GCMv2 signal names, before or after the loader
consent({ analytics: true, marketing: false });
consent({ ad_storage: "granted", ad_user_data: "granted" });
Pixel dedup
Share the loader's per-fire event id with your browser pixel so the platform collapses pixel + server into one conversion.
import { lastEventId, pushPurchase } from "@tracerkit/js";

pushPurchase(order);
// if you also run a browser pixel, share the event id so the platform
// dedupes pixel + server into ONE conversion:
fbq("track", "Purchase", { value, currency }, { eventID: lastEventId() });
Loader-optional semantics
  • During SSR (no window) every call is a silent no-op.
  • Layer pushes made before the loader boots queue on the plain window.tracerkitLayer array and are drained on boot.
  • consent() before boot stages normalized state on window.__tkConsent — the site preset the loader applies first on boot. Normalization uses the exact same helper as the loader, so category expansion (marketing ⇔ ad_storage + ad_user_data + ad_personalization) and last-write-wins ordering behave identically before and after boot.
@tracerkit/react
A component that renders the loader snippet (plain async script — no next/script) and a hook exposing the typed API.
FunctionReturnsNotes
<TracerKit siteKey="tk_..." api? preview? />JSX (a plain async <script> tag)Renders the loader snippet — no next/script, works in React 18+ and in Next.js App Router server components. api sets a verified custom-domain origin (script src + data-api); preview sets data-preview for draft configs.
useTracerKit(){ pushEvent, pushPurchase, identify, consent, lastEventId }The typed @tracerkit/js API as a stable object for event handlers and effects. All methods SSR-safe. The same functions are also re-exported from @tracerkit/react directly.

Next.js App Router: inside <head> in the root layout

// app/layout.tsx (Next.js App Router)
import { TracerKit } from "@tracerkit/react";

export default function RootLayout({
  children,
}: {
  children: React.ReactNode;
}) {
  return (
    <html lang="en">
      <head>
        {/* the loader ships in the initial HTML — the plain-script
            equivalent of next/script's beforeInteractive placement */}
        <TracerKit siteKey="tk_YOUR_SITE_KEY" />
      </head>
      <body>{children}</body>
    </html>
  );
}

Push events from client components

"use client";
import { useTracerKit } from "@tracerkit/react";

export function CheckoutButton({ cart }: { cart: Cart }) {
  const { pushEvent } = useTracerKit();
  return (
    <button
      onClick={() =>
        pushEvent("begin_checkout", {
          value: cart.total,
          currency: cart.currency,
          items: cart.items,
        })
      }
    >
      Checkout
    </button>
  );
}

Agents can read this reference as markdown at /docs/sdk.md. The SDK types mirror the data layer spec field-for-field.