Tracking Recipes
These recipes show common ways to track user interactions and application events. Copy and customize them for your needs.
Recipes
Best Practices
1. Prevent Duplicate Events
Use refs or Sets to track what's already been tracked:
const tracked = useRef(new Set<string>());
if (!tracked.current.has(eventId)) {
tracked.current.add(eventId);
track("event_name", { id: eventId });
}2. Track Only Essential Data
Avoid tracking sensitive information or excessive data:
// ✅ Good - Only essential properties
track("purchase_completed", {
order_id: "ORD-123",
revenue: 99.99,
currency: "USD",
});
// ❌ Avoid - Too much data, includes PII
track("purchase_completed", {
order_id: "ORD-123",
revenue: 99.99,
currency: "USD",
email: "user@example.com", // PII
full_address: "...", // Sensitive
credit_card_last_4: "1234", // Sensitive
});3. Use Consistent Event Names
Follow a naming convention (e.g., snake_case):
// ✅ Good - Consistent naming
track("button_clicked");
track("form_submitted");
track("modal_opened");
// ❌ Avoid - Inconsistent naming
track("buttonClick");
track("form-submitted");
track("ModalOpened");4. Handle Errors Gracefully
Don't let tracking errors break your app:
const trackSafely = useCallback((eventName: string, properties?: Record<string, unknown>) => {
try {
track(eventName, properties);
} catch (error) {
console.error("Tracking error:", error);
// Don't throw - tracking failures shouldn't break the app
}
}, []);5. Conditional Tracking
Only track in production or when explicitly enabled:
export function useToastTracking() {
const { toasts } = useSonner();
const tracked = useRef(new Set<string | number>());
const isEnabled = process.env.NODE_ENV === "production";
useEffect(() => {
if (!isEnabled) return;
for (const toast of toasts) {
if (!tracked.current.has(toast.id)) {
tracked.current.add(toast.id);
track("toast_shown", {
type: toast.type,
message: toast.title,
});
}
}
}, [toasts, isEnabled]);
}Related Documentation
How is this guide?