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
npm install @atribu/trackerQuick start
import { useEffect } from "react";
import { init } from "@atribu/tracker";
function App() {
useEffect(() => {
init({ trackingKey: "trk_live_your_key" });
}, []);
return <div>Your app</div>;
}"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:
import { AtribuProvider } from "@/components/AtribuProvider";
export default function RootLayout({ children }) {
return (
<html>
<body>
<AtribuProvider>{children}</AtribuProvider>
</body>
</html>
);
}<script setup>
import { onMounted } from "vue";
import { init } from "@atribu/tracker";
onMounted(() => {
init({ trackingKey: "trk_live_your_key" });
});
</script><script type="module">
import { init } from "@atribu/tracker";
init({ trackingKey: "trk_live_your_key" });
</script>Configuration
All options passed to init():
| Option | Type | Default | Description |
|---|---|---|---|
trackingKey | string | required | Your ingest key from Settings > Tracking |
apiHost | string | window.location.origin | Origin for the collect endpoint |
trackingEndpoint | string | {apiHost}/api/tracking/collect | Full URL override for tracking |
interceptMetaFbq | boolean | true | Intercept Meta Pixel fbq() calls for server-side deduplication |
metaBridgePageview | boolean | false | Also mirror Meta PageView events |
sessionTimeoutMinutes | number | 30 | Session inactivity timeout (1-120 min) |
sessionMode | string | "inactivity_only" | "inactivity_only" or "inactivity_or_source_change" |
heartbeatIntervalSeconds | number | false | 60 | Engagement heartbeat interval (crash-recovery checkpoint). 0 or false to disable |
enableClickQuality | boolean | true | Track rage clicks and dead clicks |
enableWebVitals | boolean | true | Capture Core Web Vitals (LCP, FCP, CLS, INP, TTFB) |
enableCtaTracking | boolean | true | Auto-detect and track CTA button visibility |
enableVideoTracking | boolean | true | Auto-detect <video> elements and track milestones |
ignoredPages | string[] | — | URL patterns to skip tracking (e.g., ["/admin/*"]) |
customProperties | object | function | — | Static properties or function merged into every event |
transformRequest | function | — | Middleware to modify or suppress events before sending |
Custom properties
init({
trackingKey: "trk_live_...",
customProperties: {
environment: "production",
appVersion: "2.1.0",
},
});init({
trackingKey: "trk_live_...",
customProperties: (ctx) => ({
currentPath: ctx.path,
isLoggedIn: !!localStorage.getItem("token"),
}),
});Transform request (middleware)
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
import { track } from "@atribu/tracker";
track("button_clicked", { buttonName: "pricing_cta" });import { trackRevenue } from "@atribu/tracker";
trackRevenue("purchase", 99.99, "USD", { plan: "Pro" });import { trackSelfDescribing } from "@atribu/tracker";
trackSelfDescribing({
eventSchema: "com.atribu.checkout",
schemaVersion: 1,
payload: { step: "payment", method: "credit_card" },
});Identifying users
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.
Consent management
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
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
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:
| Category | Events |
|---|---|
| Navigation | Page views, SPA navigation (pushState, popstate, hashchange) |
| Sessions | Session start/end, configurable timeout |
| Engagement | Scroll depth, time on page, heartbeat |
| Links | Outbound link clicks, file downloads (PDF, ZIP, etc.) |
| Forms | Form submissions with email/phone extraction |
| Bookings | GHL, Calendly, Cal.com widget completions |
| Meta Pixel | fbq() interception for server-side dedup |
| Stripe | Checkout completion detection (?session_id=cs_*) |
| GHL Forms | fetch() interception for div-based forms |
| Click Quality | Rage clicks (3+ rapid), dead clicks (optional) |
| Web Vitals | LCP, FCP, CLS, INP, TTFB (optional) |
| CTA Visibility | Action button/link visibility tracking (optional) |
| Video | <video> play/pause/milestones (optional) |
| Errors | Uncaught JavaScript errors |
| Bot Detection | Filters bots, tags AI agents (ChatGPT, Claude, etc.) |
Script tag vs npm
| npm Package | Script Tag | |
|---|---|---|
| Install | npm install @atribu/tracker | <script src="..."></script> |
| TypeScript | Full type safety | No types |
| Frameworks | React, Next.js, Vue, Svelte | Vanilla HTML only |
| SSR | Built-in no-op client | Client-side only |
| Config | Typed init() object | Window variables |
| Module | ESM + CommonJS | IIFE global |
| Functionality | Identical | Identical |
TypeScript support
All types are exported:
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.
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");