Framework Guides
Set up @atribu/tracker in React, Next.js, Vue 3, Svelte, and vanilla JavaScript
Detailed setup instructions for each framework. The @atribu/tracker package works with any JavaScript framework thanks to its SSR-safe design.
React
Create a provider component that initializes the tracker once:
import { useEffect } from "react";
import { init } from "@atribu/tracker";
export function AtribuProvider({ children }: { children: React.ReactNode }) {
useEffect(() => {
init({
trackingKey: "trk_live_your_key",
// Optional: customize behavior
sessionTimeoutMinutes: 30,
enableWebVitals: true,
});
}, []);
return <>{children}</>;
}import { AtribuProvider } from "./components/AtribuProvider";
function App() {
return (
<AtribuProvider>
<YourApp />
</AtribuProvider>
);
}Tracking events in components
import { track } from "@atribu/tracker";
export function PricingButton() {
return (
<button onClick={() => track("pricing_clicked", { plan: "pro" })}>
View Pricing
</button>
);
}Identifying users after form submission
import { identify } from "@atribu/tracker";
export function ContactForm() {
const handleSubmit = (e: React.FormEvent<HTMLFormElement>) => {
e.preventDefault();
const data = new FormData(e.currentTarget);
identify({
email: data.get("email") as string,
firstName: data.get("name") as string,
});
// Submit form...
};
return (
<form onSubmit={handleSubmit}>
<input name="name" placeholder="Name" />
<input name="email" type="email" placeholder="Email" />
<button type="submit">Submit</button>
</form>
);
}Next.js (App Router)
Client component required
The tracker uses browser APIs (window, localStorage). It must be initialized in a Client Component with the "use client" directive.
"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}</>;
}import { AtribuProvider } from "@/components/AtribuProvider";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<html lang="en">
<body>
<AtribuProvider>{children}</AtribuProvider>
</body>
</html>
);
}SSR safe
If you accidentally import @atribu/tracker in a Server Component, init() returns a silent no-op client. No errors, no crashes — it simply does nothing until running in the browser.
Vue 3
<script setup lang="ts">
import { onMounted } from "vue";
import { init } from "@atribu/tracker";
onMounted(() => {
init({ trackingKey: "trk_live_your_key" });
});
</script>
<template>
<RouterView />
</template>Tracking events
<script setup lang="ts">
import { track } from "@atribu/tracker";
function handleClick() {
track("pricing_clicked", { plan: "pro" });
}
</script>
<template>
<button @click="handleClick">View Pricing</button>
</template>Svelte
<script>
import { onMount } from "svelte";
import { init } from "@atribu/tracker";
onMount(() => {
init({ trackingKey: "trk_live_your_key" });
});
</script>
<slot />Vanilla JavaScript
<script type="module">
import { init, track, identify } from "@atribu/tracker";
init({ trackingKey: "trk_live_your_key" });
// Track a custom event
document.querySelector("#cta").addEventListener("click", () => {
track("cta_clicked");
});
// Identify after form submit
document.querySelector("form").addEventListener("submit", (e) => {
const email = e.target.querySelector('[name="email"]').value;
identify({ email });
});
</script>SPA navigation
The tracker automatically detects Single Page App navigation via:
history.pushStateandhistory.replaceStateinterceptionpopstateevent listenerhashchangeevent listener
Each navigation fires a new page_view event and resets engagement tracking (scroll depth, time on page). No additional configuration needed.
SSR environments
In server-side rendering (Next.js, Nuxt, SvelteKit SSR), the tracker handles the missing window gracefully:
init()detectstypeof window === "undefined"- Returns a no-op client where all methods (
track,identify, etc.) are empty functions - No errors thrown, no
window is not definedcrashes - When the code later runs in the browser,
init()activates normally
This means you can safely import and call tracker functions anywhere — server or client.