|
| 1 | +--- |
| 2 | +title: Hook Examples |
| 3 | +description: Example React hooks for tracking custom events and user interactions |
| 4 | +--- |
| 5 | + |
| 6 | +import { CodeBlock } from "@/components/docs"; |
| 7 | +import { Callout } from "@/components/docs"; |
| 8 | +import { Card, Cards } from "@/components/docs"; |
| 9 | + |
| 10 | +<Callout type="info"> |
| 11 | + <strong>TL;DR</strong> — **Example hooks** you can copy and customize to track custom events in your application. **Track only what you need** and **avoid duplicate events**. |
| 12 | +</Callout> |
| 13 | + |
| 14 | +These are example React hooks for tracking common user interactions and application events. Copy and customize them for your needs. |
| 15 | + |
| 16 | +## Example Hooks |
| 17 | + |
| 18 | +<Cards> |
| 19 | + <Card title="Toast Tracking" href="/docs/hooks/toast-tracking"> |
| 20 | + Track toast notifications automatically to understand user feedback patterns and error rates |
| 21 | + </Card> |
| 22 | + <Card title="Form Tracking" href="/docs/hooks/form-tracking"> |
| 23 | + Track form submissions with validation state and error patterns |
| 24 | + </Card> |
| 25 | + <Card title="Modal Tracking" href="/docs/hooks/modal-tracking"> |
| 26 | + Track when modals and dialogs are opened and closed |
| 27 | + </Card> |
| 28 | + <Card title="Feature Usage" href="/docs/hooks/feature-usage"> |
| 29 | + Track when users interact with specific features |
| 30 | + </Card> |
| 31 | + <Card title="Feedback Tracking" href="/docs/hooks/feedback-tracking"> |
| 32 | + Track user feedback with server actions and client hooks |
| 33 | + </Card> |
| 34 | +</Cards> |
| 35 | + |
| 36 | +## Best Practices |
| 37 | + |
| 38 | +### 1. Prevent Duplicate Events |
| 39 | + |
| 40 | +Use refs or Sets to track what's already been tracked: |
| 41 | + |
| 42 | +<CodeBlock |
| 43 | + language="tsx" |
| 44 | + code={`const tracked = useRef(new Set<string>()); |
| 45 | +
|
| 46 | +if (!tracked.current.has(eventId)) { |
| 47 | + tracked.current.add(eventId); |
| 48 | + track("event_name", { id: eventId }); |
| 49 | +}`} |
| 50 | +/> |
| 51 | + |
| 52 | +### 2. Track Only Essential Data |
| 53 | + |
| 54 | +Avoid tracking sensitive information or excessive data: |
| 55 | + |
| 56 | +<CodeBlock |
| 57 | + language="tsx" |
| 58 | + code={`// ✅ Good - Only essential properties |
| 59 | +track("purchase_completed", { |
| 60 | + order_id: "ORD-123", |
| 61 | + revenue: 99.99, |
| 62 | + currency: "USD", |
| 63 | +}); |
| 64 | +
|
| 65 | +// ❌ Avoid - Too much data, includes PII |
| 66 | +track("purchase_completed", { |
| 67 | + order_id: "ORD-123", |
| 68 | + revenue: 99.99, |
| 69 | + currency: "USD", |
| 70 | + email: "[email protected]", // PII |
| 71 | + full_address: "...", // Sensitive |
| 72 | + credit_card_last_4: "1234", // Sensitive |
| 73 | +});`} |
| 74 | +/> |
| 75 | + |
| 76 | +### 3. Use Consistent Event Names |
| 77 | + |
| 78 | +Follow a naming convention (e.g., `snake_case`): |
| 79 | + |
| 80 | +<CodeBlock |
| 81 | + language="tsx" |
| 82 | + code={`// ✅ Good - Consistent naming |
| 83 | +track("button_clicked"); |
| 84 | +track("form_submitted"); |
| 85 | +track("modal_opened"); |
| 86 | +
|
| 87 | +// ❌ Avoid - Inconsistent naming |
| 88 | +track("buttonClick"); |
| 89 | +track("form-submitted"); |
| 90 | +track("ModalOpened");`} |
| 91 | +/> |
| 92 | + |
| 93 | +### 4. Handle Errors Gracefully |
| 94 | + |
| 95 | +Don't let tracking errors break your app: |
| 96 | + |
| 97 | +<CodeBlock |
| 98 | + language="tsx" |
| 99 | + code={`const trackSafely = useCallback((eventName: string, properties?: Record<string, unknown>) => { |
| 100 | + try { |
| 101 | + track(eventName, properties); |
| 102 | + } catch (error) { |
| 103 | + console.error("Tracking error:", error); |
| 104 | + // Don't throw - tracking failures shouldn't break the app |
| 105 | + } |
| 106 | +}, []);`} |
| 107 | +/> |
| 108 | + |
| 109 | +### 5. Conditional Tracking |
| 110 | + |
| 111 | +Only track in production or when explicitly enabled: |
| 112 | + |
| 113 | +<CodeBlock |
| 114 | + language="tsx" |
| 115 | + code={`export function useToastTracking() { |
| 116 | + const { toasts } = useSonner(); |
| 117 | + const tracked = useRef(new Set<string | number>()); |
| 118 | + const isEnabled = process.env.NODE_ENV === "production"; |
| 119 | +
|
| 120 | + useEffect(() => { |
| 121 | + if (!isEnabled) return; |
| 122 | +
|
| 123 | + for (const toast of toasts) { |
| 124 | + if (!tracked.current.has(toast.id)) { |
| 125 | + tracked.current.add(toast.id); |
| 126 | + track("toast_shown", { |
| 127 | + type: toast.type, |
| 128 | + message: toast.title, |
| 129 | + }); |
| 130 | + } |
| 131 | + } |
| 132 | + }, [toasts, isEnabled]); |
| 133 | +}`} |
| 134 | +/> |
| 135 | + |
| 136 | +## Related Documentation |
| 137 | + |
| 138 | +<Cards> |
| 139 | + <Card title="SDK Reference" href="/docs/sdk" icon="📚"> |
| 140 | + Complete SDK API reference and configuration options |
| 141 | + </Card> |
| 142 | + <Card title="React Integration" href="/docs/Integrations/react" icon="⚛️"> |
| 143 | + React-specific integration guide and examples |
| 144 | + </Card> |
| 145 | + <Card title="Custom Events" href="/docs/sdk#custom-event-tracking" icon="🎯"> |
| 146 | + Learn more about custom event tracking patterns |
| 147 | + </Card> |
| 148 | +</Cards> |
| 149 | + |
0 commit comments