Introduction
Motivation
Event tracking is a complex task that requires a lot of boilerplate code and complexity.
Take a look at this example.
// Traditional event tracking
const Page = () => {
const { user, userId } = useUser();
return (
<div>
<p>User: {user.name}</p>
<Counter userId={userId} />
</div>
);
};
const Counter = ({ userId }: { userId: string }) => {
// Receives 'userId' as a prop just for event tracking purposes.
const [count, setCount] = useState(0);
const { track } = useTrackEvent();
const handleIncrement = () => {
setCount(count + 1);
track({
event: "click",
params: {
type: "count",
value: count + 1,
userId,
},
});
};
return (
<div>
<p>Count: {count}</p>
<button onClick={handleIncrement}>Increment</button>
</div>
);
};
The two main inconveniences caused by event tracking in the code are:
- Prop Drilling: The
userId
is passed as a prop to the<Counter />
component from the<Page />
component. If the<Counter />
component is nested deeper within the component tree, prop drilling can become more severe, reducing the readability and maintainability of the code. - Coupling of Event Tracking Logic and Business Logic: The
handleIncrement
function contains both the logic for incrementing the count and tracking the event. Separating the event tracking logic can make the code cleaner and easier to maintain.
The New Paradigm
event-tracker
introduces a new paradigm for event tracking.
The declarative nature of this paradigm simplifies
the complexity traditionally associated with event tracking, making it accessible to developers of all skill levels.
Declarative event tracking
const Page = () => {
const { user, userId } = useUser();
return (
<Track.Provider initialContext={{ userId }}>
<div>
<p>User: {user.name}</p>
<Counter />
</div>
</Track.Provider>
);
};
const Counter = () => {
const [count, setCount] = useState(0);
const handleIncrement = () => {
setCount(count + 1);
};
return (
<div>
<p>Count: {count}</p>
<Track.Click params={{ value: count + 1, type: "count" }}>
<button onClick={handleIncrement}>Increment</button>
</Track.Click>
</div>
);
};
Using event-tracker
allows for declarative event tracking, which improves code readability and reduces complexity. This helps developers understand and use event tracking more easily.
Your handleIncrement
function is now only responsible for incrementing the count, and the event tracking is handled by the <Track.Click />
component.
This declarative approach makes the developer focus on ‘what to track’ and not ‘how to track’.
How to track should be defined outside of the React app.
Improve code cohesion outside your application.
const [Track] = createTracker({
DOMEvents: {
onClick: (params, context) => {
log({
event: "click",
params: {
...params,
userId: context.userId,
},
});
},
},
onImpression: (params, context) => {
log({
event: "impression",
params: {
...params,
userId: context.userId,
},
});
},
});
Your instructions for ‘how to track’ is now separated from your business logic.
It’s located outside your application, so you can change your event tracking provider without having to change your application code.
Key Features
- 🎯 Type-safe APIs: Declarative event tracking with complete type safety
- ⚡️ Optimized Performance: Enhanced performance through event batching
- 🔄 Guaranteed Order: Guaranteed execution order for async operations
- 🔌 Analytics Agnostic: Works with any analytics provider of your choice
- 🧩 Clean Separation: Keeps tracking logic separate from business logic
- 📦 Lightweight: Minimal bundle size impact on your application
Basic Concepts
event-tracker
is built around a few core concepts:
- Tracker Creation: Use
createTracker
to create a tracker instance with your desired event tracking instructions. - Provider: Wrap your app with
Track.Provider
to provide context. - Event Components: Use components like
Track.Click
orTrack.Impression
to track events. - Hooks: Use the
useTracker
hook to access tracking functionality in your components imperatively.
Check out the other sections for detailed documentation on each feature:
- createTracker - Detailed API documentation on
createTracker
- components - Available tracking components
- hook - Track using the hook
- Batching - Optimizing performance with event batching