Atribu
Tracking

npm Package (@atribu/tracker)

Official TypeScript SDK for Atribu — install via npm for full type safety, framework integration, and SSR support

The @atribu/tracker npm package is the official TypeScript SDK for Atribu. It bundles the full tracker runtime with type-safe configuration, framework-agnostic design, and automatic SSR safety.

Installation

Install
npm install @atribu/tracker

Quick start

src/App.tsx
import { useEffect } from "react";
import { init } from "@atribu/tracker";

function App() {
  useEffect(() => {
    init({ trackingKey: "trk_live_your_key" });
  }, []);

  return <div>Your app</div>;
}
src/components/AtribuProvider.tsx
"use client";

import { useEffect } from "react";
import { init } from "@atribu/tracker";

export function AtribuProvider({ children }: { children: React.ReactNode }) {
  useEffect(() => {
    init({ trackingKey: "trk_live_your_key" });
  }, []);

  return <>{children}</>;
}

Then wrap your root layout:

src/app/layout.tsx
import { AtribuProvider } from "@/components/AtribuProvider";

export default function RootLayout({ children }) {
  return (
    <html>
      <body>
        <AtribuProvider>{children}</AtribuProvider>
      </body>
    </html>
  );
}
src/App.vue
<script setup>
import { onMounted } from "vue";
import { init } from "@atribu/tracker";

onMounted(() => {
  init({ trackingKey: "trk_live_your_key" });
});
</script>
index.html
<script type="module">
  import { init } from "@atribu/tracker";
  init({ trackingKey: "trk_live_your_key" });
</script>

Configuration

All options passed to init():

OptionTypeDefaultDescription
trackingKeystringrequiredYour ingest key from Settings > Tracking
apiHoststringwindow.location.originOrigin for the collect endpoint
trackingEndpointstring{apiHost}/api/tracking/collectFull URL override for tracking
interceptMetaFbqbooleantrueIntercept Meta Pixel fbq() calls for server-side deduplication
metaBridgePageviewbooleanfalseAlso mirror Meta PageView events
sessionTimeoutMinutesnumber30Session inactivity timeout (1-120 min)
sessionModestring"inactivity_only""inactivity_only" or "inactivity_or_source_change"
heartbeatIntervalSecondsnumber | false60Engagement heartbeat interval (crash-recovery checkpoint). 0 or false to disable
enableClickQualitybooleantrueTrack rage clicks and dead clicks
enableWebVitalsbooleantrueCapture Core Web Vitals (LCP, FCP, CLS, INP, TTFB)
enableCtaTrackingbooleantrueAuto-detect and track CTA button visibility
enableVideoTrackingbooleantrueAuto-detect <video> elements and track milestones
ignoredPagesstring[]URL patterns to skip tracking (e.g., ["/admin/*"])
customPropertiesobject | functionStatic properties or function merged into every event
transformRequestfunctionMiddleware to modify or suppress events before sending

Custom properties

Static properties
init({
  trackingKey: "trk_live_...",
  customProperties: {
    environment: "production",
    appVersion: "2.1.0",
  },
});
Dynamic properties (function)
init({
  trackingKey: "trk_live_...",
  customProperties: (ctx) => ({
    currentPath: ctx.path,
    isLoggedIn: !!localStorage.getItem("token"),
  }),
});

Transform request (middleware)

Filter out events
init({
  trackingKey: "trk_live_...",
  transformRequest: (event) => {
    // Suppress events from admin pages
    if (event.path?.startsWith("/admin")) return null;
    // Add custom header
    event.payload.buildId = "abc123";
    return event;
  },
});

Tracking events

Basic event
import { track } from "@atribu/tracker";

track("button_clicked", { buttonName: "pricing_cta" });
Revenue event
import { trackRevenue } from "@atribu/tracker";

trackRevenue("purchase", 99.99, "USD", { plan: "Pro" });
Self-describing event (with schema)
import { trackSelfDescribing } from "@atribu/tracker";

trackSelfDescribing({
  eventSchema: "com.atribu.checkout",
  schemaVersion: 1,
  payload: { step: "payment", method: "credit_card" },
});

Identifying users

Identify after form submission
import { identify } from "@atribu/tracker";

identify({
  email: "[email protected]",
  firstName: "Jane",
  lastName: "Smith",
  phone: "+1-555-0123",
});

Critical for attribution

Without identify(), anonymous visitors cannot be linked to payments or CRM events. Call it on every form submission, login, or signup. See User Identification for details.

Set consent after cookie banner
import { setConsent } from "@atribu/tracker";

// After user accepts analytics cookies
setConsent({ analytics: true, marketing: false });

Consent state is persisted in localStorage and attached to every subsequent event.

Impressions

Track when an element becomes visible
import { observeImpression } from "@atribu/tracker";

// CSS selector
const cleanup = observeImpression("#hero-banner", { section: "hero" });

// DOM element
const el = document.querySelector(".pricing-card");
const cleanup2 = observeImpression(el, { plan: "pro" }, { threshold: 0.8 });

// Cleanup on unmount
cleanup();
cleanup2();

Lifecycle

Flush and reset
import { flush, reset } from "@atribu/tracker";

// Force-send all queued events (before navigation)
flush();

// Clear all stored state (on logout)
reset();

Auto-captured events

The package automatically captures these events with zero configuration:

CategoryEvents
NavigationPage views, SPA navigation (pushState, popstate, hashchange)
SessionsSession start/end, configurable timeout
EngagementScroll depth, time on page, heartbeat
LinksOutbound link clicks, file downloads (PDF, ZIP, etc.)
FormsForm submissions with email/phone extraction
BookingsGHL, Calendly, Cal.com widget completions
Meta Pixelfbq() interception for server-side dedup
StripeCheckout completion detection (?session_id=cs_*)
GHL Formsfetch() interception for div-based forms
Click QualityRage clicks (3+ rapid), dead clicks (optional)
Web VitalsLCP, FCP, CLS, INP, TTFB (optional)
CTA VisibilityAction button/link visibility tracking (optional)
Video<video> play/pause/milestones (optional)
ErrorsUncaught JavaScript errors
Bot DetectionFilters bots, tags AI agents (ChatGPT, Claude, etc.)

Script tag vs npm

npm PackageScript Tag
Installnpm install @atribu/tracker<script src="..."></script>
TypeScriptFull type safetyNo types
FrameworksReact, Next.js, Vue, SvelteVanilla HTML only
SSRBuilt-in no-op clientClient-side only
ConfigTyped init() objectWindow variables
ModuleESM + CommonJSIIFE global
FunctionalityIdenticalIdentical

TypeScript support

All types are exported:

Import types
import type {
  AtribuConfig,
  AtribuClient,
  TrackOptions,
  IdentifyInput,
  ConsentPayload,
  TrackingEvent,
} from "@atribu/tracker";

SSR safety

When window is undefined (Node.js, Next.js server components, SSR), init() returns a silent no-op client. All methods (track, identify, etc.) are safe to call — they simply do nothing server-side and activate once the code runs in the browser.

Safe in any environment
import { init, track } from "@atribu/tracker";

// This works in SSR — returns no-op client, no errors
const client = init({ trackingKey: "trk_live_..." });

// This is safe server-side — silently ignored
track("page_loaded");

On this page