@journium/react 0.1.0-alpha.3 → 0.1.0-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/hooks.d.ts +2 -0
- package/dist/hooks.d.ts.map +1 -1
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +91 -1
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +91 -1
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
- package/readme.md +259 -289
package/readme.md
CHANGED
|
@@ -30,10 +30,12 @@ function Root() {
|
|
|
30
30
|
<JourniumProvider
|
|
31
31
|
config={{
|
|
32
32
|
token: "your-journium-token",
|
|
33
|
-
apiHost: "https://your-journium-instance.com"
|
|
34
|
-
|
|
33
|
+
apiHost: "https://your-journium-instance.com",
|
|
34
|
+
debug: true, // Optional: Enable debug logging
|
|
35
|
+
flushAt: 5, // Optional: Send events after 5 events
|
|
36
|
+
flushInterval: 10000 // Optional: Send events every 10 seconds
|
|
35
37
|
}}
|
|
36
|
-
autoCapture={true} // Enables auto-pageview and
|
|
38
|
+
autoCapture={true} // Enables auto-pageview and click tracking
|
|
37
39
|
>
|
|
38
40
|
<App />
|
|
39
41
|
</JourniumProvider>
|
|
@@ -43,20 +45,21 @@ function Root() {
|
|
|
43
45
|
export default Root;
|
|
44
46
|
```
|
|
45
47
|
|
|
46
|
-
###
|
|
48
|
+
### Track Custom Events
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
Use the `useTrackEvent` hook to track custom events:
|
|
49
51
|
|
|
50
52
|
```jsx
|
|
51
53
|
import React from 'react';
|
|
52
|
-
import {
|
|
54
|
+
import { useTrackEvent } from '@journium/react';
|
|
53
55
|
|
|
54
56
|
function SignupButton() {
|
|
55
|
-
const
|
|
57
|
+
const trackEvent = useTrackEvent();
|
|
56
58
|
|
|
57
59
|
const handleSignup = () => {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
+
trackEvent('user_signup', {
|
|
61
|
+
method: 'email',
|
|
62
|
+
source: 'landing_page',
|
|
60
63
|
plan: 'free'
|
|
61
64
|
});
|
|
62
65
|
// Your signup logic
|
|
@@ -66,71 +69,161 @@ function SignupButton() {
|
|
|
66
69
|
}
|
|
67
70
|
```
|
|
68
71
|
|
|
69
|
-
## 📖
|
|
72
|
+
## 📖 Tracking Hooks
|
|
70
73
|
|
|
71
|
-
###
|
|
74
|
+
### useTrackEvent - Track Custom Events
|
|
72
75
|
|
|
73
|
-
The
|
|
76
|
+
The primary hook for tracking custom business events:
|
|
74
77
|
|
|
75
78
|
```jsx
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
79
|
+
import { useTrackEvent } from '@journium/react';
|
|
80
|
+
|
|
81
|
+
function EcommerceComponent() {
|
|
82
|
+
const trackEvent = useTrackEvent();
|
|
83
|
+
|
|
84
|
+
const handlePurchase = () => {
|
|
85
|
+
trackEvent('purchase_completed', {
|
|
86
|
+
product_id: 'prod_123',
|
|
87
|
+
price: 29.99,
|
|
88
|
+
currency: 'USD',
|
|
89
|
+
category: 'electronics'
|
|
90
|
+
});
|
|
91
|
+
};
|
|
92
|
+
|
|
93
|
+
const handleAddToCart = () => {
|
|
94
|
+
trackEvent('product_added_to_cart', {
|
|
95
|
+
product_id: 'prod_123',
|
|
96
|
+
quantity: 1,
|
|
97
|
+
source: 'product_page'
|
|
98
|
+
});
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
return (
|
|
102
|
+
<div>
|
|
103
|
+
<button onClick={handleAddToCart}>Add to Cart</button>
|
|
104
|
+
<button onClick={handlePurchase}>Buy Now</button>
|
|
105
|
+
</div>
|
|
106
|
+
);
|
|
107
|
+
}
|
|
87
108
|
```
|
|
88
109
|
|
|
89
|
-
###
|
|
110
|
+
### useIdentify - User Identification
|
|
90
111
|
|
|
91
|
-
|
|
112
|
+
Use this hook to identify users when they log in or sign up. This should be used instead of tracking user login as a custom event.
|
|
92
113
|
|
|
93
114
|
```jsx
|
|
94
|
-
import {
|
|
95
|
-
|
|
96
|
-
function MyComponent() {
|
|
97
|
-
const { track, capturePageview, startAutoCapture, stopAutoCapture, flush } = useJournium();
|
|
115
|
+
import { useIdentify } from '@journium/react';
|
|
98
116
|
|
|
99
|
-
|
|
100
|
-
const
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
117
|
+
function LoginForm() {
|
|
118
|
+
const identify = useIdentify();
|
|
119
|
+
|
|
120
|
+
const handleLogin = async (email, password) => {
|
|
121
|
+
try {
|
|
122
|
+
const user = await loginUser(email, password);
|
|
123
|
+
|
|
124
|
+
// Identify the user after successful login
|
|
125
|
+
identify(user.id, {
|
|
126
|
+
name: user.name,
|
|
127
|
+
email: user.email,
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
// Redirect to dashboard or show success
|
|
131
|
+
} catch (error) {
|
|
132
|
+
// Handle login error
|
|
133
|
+
}
|
|
105
134
|
};
|
|
106
135
|
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
136
|
+
return (
|
|
137
|
+
<form onSubmit={handleLogin}>
|
|
138
|
+
{/* Login form fields */}
|
|
139
|
+
</form>
|
|
140
|
+
);
|
|
141
|
+
}
|
|
142
|
+
```
|
|
114
143
|
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
144
|
+
### useReset - User Logout
|
|
145
|
+
|
|
146
|
+
Use this hook to reset user identity when they log out:
|
|
147
|
+
|
|
148
|
+
```jsx
|
|
149
|
+
import { useReset } from '@journium/react';
|
|
150
|
+
|
|
151
|
+
function LogoutButton() {
|
|
152
|
+
const reset = useReset();
|
|
153
|
+
|
|
154
|
+
const handleLogout = async () => {
|
|
155
|
+
try {
|
|
156
|
+
await logoutUser();
|
|
157
|
+
|
|
158
|
+
// Reset user identity after successful logout
|
|
159
|
+
reset();
|
|
160
|
+
|
|
161
|
+
// Redirect to home or login page
|
|
162
|
+
} catch (error) {
|
|
163
|
+
// Handle logout error
|
|
121
164
|
}
|
|
122
165
|
};
|
|
123
166
|
|
|
167
|
+
return <button onClick={handleLogout}>Log Out</button>;
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
### useTrackPageview - Manual Pageview Tracking
|
|
172
|
+
|
|
173
|
+
For tracking custom pageviews beyond automatic route tracking:
|
|
174
|
+
|
|
175
|
+
```jsx
|
|
176
|
+
import { useTrackPageview } from '@journium/react';
|
|
177
|
+
|
|
178
|
+
function CustomPageTracker() {
|
|
179
|
+
const trackPageview = useTrackPageview();
|
|
180
|
+
|
|
181
|
+
const handleSpecialPageview = () => {
|
|
182
|
+
trackPageview({
|
|
183
|
+
page_type: 'modal',
|
|
184
|
+
content_type: 'pricing_calculator',
|
|
185
|
+
user_segment: 'premium'
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
|
|
124
189
|
return (
|
|
125
|
-
<
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
<button onClick={toggleTracking}>Toggle Tracking</button>
|
|
129
|
-
</div>
|
|
190
|
+
<button onClick={handleSpecialPageview}>
|
|
191
|
+
Track Modal View
|
|
192
|
+
</button>
|
|
130
193
|
);
|
|
131
194
|
}
|
|
132
195
|
```
|
|
133
196
|
|
|
197
|
+
### useAutoTrackPageview - Automatic Pageview on Mount
|
|
198
|
+
|
|
199
|
+
Automatically track pageviews when components mount or dependencies change:
|
|
200
|
+
|
|
201
|
+
```jsx
|
|
202
|
+
import { useAutoTrackPageview } from '@journium/react';
|
|
203
|
+
|
|
204
|
+
function ProductPage({ productId, category }) {
|
|
205
|
+
// Tracks pageview when component mounts or productId changes
|
|
206
|
+
useAutoTrackPageview([productId], {
|
|
207
|
+
page_type: 'product_detail',
|
|
208
|
+
product_id: productId,
|
|
209
|
+
category: category
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
return <div>Product {productId}</div>;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function BlogPost({ postId }) {
|
|
216
|
+
// Track pageview for blog posts
|
|
217
|
+
useAutoTrackPageview([postId], {
|
|
218
|
+
page_type: 'blog_post',
|
|
219
|
+
post_id: postId,
|
|
220
|
+
content_type: 'article'
|
|
221
|
+
});
|
|
222
|
+
|
|
223
|
+
return <article>Blog post content</article>;
|
|
224
|
+
}
|
|
225
|
+
```
|
|
226
|
+
|
|
134
227
|
## 🔧 Advanced Usage
|
|
135
228
|
|
|
136
229
|
### Form Tracking
|
|
@@ -138,27 +231,27 @@ function MyComponent() {
|
|
|
138
231
|
Track form interactions and submissions:
|
|
139
232
|
|
|
140
233
|
```jsx
|
|
141
|
-
import {
|
|
234
|
+
import { useTrackEvent } from '@journium/react';
|
|
142
235
|
|
|
143
236
|
function ContactForm() {
|
|
144
|
-
const
|
|
237
|
+
const trackEvent = useTrackEvent();
|
|
145
238
|
|
|
146
239
|
const handleSubmit = (e) => {
|
|
147
240
|
e.preventDefault();
|
|
148
241
|
|
|
149
|
-
|
|
242
|
+
trackEvent('form_submitted', {
|
|
150
243
|
form_name: 'contact',
|
|
151
244
|
form_type: 'lead_generation',
|
|
152
|
-
|
|
245
|
+
fields_completed: ['name', 'email', 'company']
|
|
153
246
|
});
|
|
154
247
|
|
|
155
248
|
// Submit form logic
|
|
156
249
|
};
|
|
157
250
|
|
|
158
|
-
const handleFieldChange = (
|
|
159
|
-
|
|
251
|
+
const handleFieldChange = (fieldName) => {
|
|
252
|
+
trackEvent('form_field_completed', {
|
|
160
253
|
form_name: 'contact',
|
|
161
|
-
field_name:
|
|
254
|
+
field_name: fieldName
|
|
162
255
|
});
|
|
163
256
|
};
|
|
164
257
|
|
|
@@ -180,174 +273,96 @@ function ContactForm() {
|
|
|
180
273
|
}
|
|
181
274
|
```
|
|
182
275
|
|
|
183
|
-
###
|
|
276
|
+
### User Journey Tracking
|
|
184
277
|
|
|
185
|
-
Track
|
|
278
|
+
Track multi-step user flows:
|
|
186
279
|
|
|
187
280
|
```jsx
|
|
188
|
-
import {
|
|
281
|
+
import { useTrackEvent, useTrackPageview } from '@journium/react';
|
|
189
282
|
|
|
190
|
-
function
|
|
191
|
-
const
|
|
283
|
+
function OnboardingFlow({ step }) {
|
|
284
|
+
const trackEvent = useTrackEvent();
|
|
285
|
+
const trackPageview = useTrackPageview();
|
|
192
286
|
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
currency: 'USD'
|
|
287
|
+
useEffect(() => {
|
|
288
|
+
// Track onboarding step pageview
|
|
289
|
+
trackPageview({
|
|
290
|
+
page_type: 'onboarding',
|
|
291
|
+
step: step,
|
|
292
|
+
flow: 'user_setup'
|
|
200
293
|
});
|
|
201
|
-
};
|
|
294
|
+
}, [step, trackPageview]);
|
|
202
295
|
|
|
203
|
-
const
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
products: orderData.items.map(item => ({
|
|
209
|
-
product_id: item.id,
|
|
210
|
-
quantity: item.quantity,
|
|
211
|
-
price: item.price
|
|
212
|
-
}))
|
|
296
|
+
const handleStepComplete = () => {
|
|
297
|
+
trackEvent('onboarding_step_completed', {
|
|
298
|
+
step: step,
|
|
299
|
+
time_spent: Date.now() - stepStartTime,
|
|
300
|
+
completed_successfully: true
|
|
213
301
|
});
|
|
214
302
|
};
|
|
215
303
|
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
<button onClick={handleAddToCart}>Add to Cart</button>
|
|
221
|
-
</div>
|
|
222
|
-
);
|
|
223
|
-
}
|
|
224
|
-
```
|
|
225
|
-
|
|
226
|
-
### React Router Integration
|
|
227
|
-
|
|
228
|
-
Track page navigation automatically:
|
|
229
|
-
|
|
230
|
-
```jsx
|
|
231
|
-
import { useEffect } from 'react';
|
|
232
|
-
import { useLocation } from 'react-router-dom';
|
|
233
|
-
import { useJournium } from '@journium/react';
|
|
234
|
-
|
|
235
|
-
function PageTracker() {
|
|
236
|
-
const location = useLocation();
|
|
237
|
-
const { capturePageview } = useJournium();
|
|
238
|
-
|
|
239
|
-
useEffect(() => {
|
|
240
|
-
capturePageview({
|
|
241
|
-
path: location.pathname,
|
|
242
|
-
search: location.search,
|
|
243
|
-
referrer: document.referrer
|
|
304
|
+
const handleSkipStep = () => {
|
|
305
|
+
trackEvent('onboarding_step_skipped', {
|
|
306
|
+
step: step,
|
|
307
|
+
reason: 'user_choice'
|
|
244
308
|
});
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
return null;
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// Add to your router setup
|
|
251
|
-
function App() {
|
|
252
|
-
return (
|
|
253
|
-
<Router>
|
|
254
|
-
<PageTracker />
|
|
255
|
-
<Routes>
|
|
256
|
-
{/* Your routes */}
|
|
257
|
-
</Routes>
|
|
258
|
-
</Router>
|
|
259
|
-
);
|
|
260
|
-
}
|
|
261
|
-
```
|
|
262
|
-
|
|
263
|
-
### Conditional Tracking
|
|
264
|
-
|
|
265
|
-
Control tracking based on user preferences or environment:
|
|
266
|
-
|
|
267
|
-
```jsx
|
|
268
|
-
import { useJournium } from '@journium/react';
|
|
269
|
-
|
|
270
|
-
function ConditionalTracker() {
|
|
271
|
-
const { track, startAutoCapture, stopAutoCapture } = useJournium();
|
|
272
|
-
const [hasConsent, setHasConsent] = useState(false);
|
|
273
|
-
|
|
274
|
-
useEffect(() => {
|
|
275
|
-
if (hasConsent) {
|
|
276
|
-
startAutoCapture();
|
|
277
|
-
track('tracking_consent_given');
|
|
278
|
-
} else {
|
|
279
|
-
stopAutoCapture();
|
|
280
|
-
}
|
|
281
|
-
}, [hasConsent, startAutoCapture, stopAutoCapture, track]);
|
|
309
|
+
};
|
|
282
310
|
|
|
283
311
|
return (
|
|
284
312
|
<div>
|
|
285
|
-
<
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
checked={hasConsent}
|
|
289
|
-
onChange={(e) => setHasConsent(e.target.checked)}
|
|
290
|
-
/>
|
|
291
|
-
Allow analytics tracking
|
|
292
|
-
</label>
|
|
313
|
+
<h2>Step {step}</h2>
|
|
314
|
+
<button onClick={handleStepComplete}>Complete Step</button>
|
|
315
|
+
<button onClick={handleSkipStep}>Skip</button>
|
|
293
316
|
</div>
|
|
294
317
|
);
|
|
295
318
|
}
|
|
296
319
|
```
|
|
297
320
|
|
|
298
|
-
###
|
|
321
|
+
### Feature Usage Tracking
|
|
299
322
|
|
|
300
|
-
Create reusable tracking
|
|
323
|
+
Create reusable tracking patterns:
|
|
301
324
|
|
|
302
325
|
```jsx
|
|
303
|
-
import {
|
|
304
|
-
|
|
305
|
-
function useUserActions() {
|
|
306
|
-
const { track } = useJournium();
|
|
326
|
+
import { useTrackEvent } from '@journium/react';
|
|
307
327
|
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
selected_plan: plan,
|
|
312
|
-
timestamp: new Date().toISOString()
|
|
313
|
-
});
|
|
314
|
-
};
|
|
328
|
+
// Custom hook for feature tracking
|
|
329
|
+
function useFeatureTracking() {
|
|
330
|
+
const trackEvent = useTrackEvent();
|
|
315
331
|
|
|
316
|
-
const
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
timestamp: new Date().toISOString()
|
|
332
|
+
const trackFeatureUsed = (featureName, context = {}) => {
|
|
333
|
+
trackEvent('feature_used', {
|
|
334
|
+
feature_name: featureName,
|
|
335
|
+
timestamp: new Date().toISOString(),
|
|
336
|
+
...context
|
|
320
337
|
});
|
|
321
338
|
};
|
|
322
339
|
|
|
323
|
-
const
|
|
324
|
-
|
|
325
|
-
feature_name:
|
|
326
|
-
|
|
327
|
-
timestamp: new Date().toISOString()
|
|
340
|
+
const trackFeatureDiscovered = (featureName, discoveryMethod) => {
|
|
341
|
+
trackEvent('feature_discovered', {
|
|
342
|
+
feature_name: featureName,
|
|
343
|
+
discovery_method: discoveryMethod
|
|
328
344
|
});
|
|
329
345
|
};
|
|
330
346
|
|
|
331
|
-
return {
|
|
332
|
-
trackSignup,
|
|
333
|
-
trackLogin,
|
|
334
|
-
trackFeatureUsed
|
|
335
|
-
};
|
|
347
|
+
return { trackFeatureUsed, trackFeatureDiscovered };
|
|
336
348
|
}
|
|
337
349
|
|
|
338
350
|
// Usage in components
|
|
339
|
-
function
|
|
340
|
-
const {
|
|
351
|
+
function AdvancedFeature() {
|
|
352
|
+
const { trackFeatureUsed, trackFeatureDiscovered } = useFeatureTracking();
|
|
341
353
|
|
|
342
|
-
const
|
|
343
|
-
|
|
344
|
-
|
|
354
|
+
const handleFeatureClick = () => {
|
|
355
|
+
trackFeatureUsed('advanced_search', {
|
|
356
|
+
search_type: 'filters',
|
|
357
|
+
filter_count: 3
|
|
358
|
+
});
|
|
345
359
|
};
|
|
346
360
|
|
|
347
361
|
return (
|
|
348
362
|
<div>
|
|
349
|
-
<button onClick={
|
|
350
|
-
|
|
363
|
+
<button onClick={handleFeatureClick}>
|
|
364
|
+
Use Advanced Search
|
|
365
|
+
</button>
|
|
351
366
|
</div>
|
|
352
367
|
);
|
|
353
368
|
}
|
|
@@ -357,41 +372,43 @@ function LoginForm() {
|
|
|
357
372
|
|
|
358
373
|
### User Consent Management
|
|
359
374
|
|
|
375
|
+
Control tracking based on user consent:
|
|
376
|
+
|
|
360
377
|
```jsx
|
|
361
378
|
import { useState, useEffect } from 'react';
|
|
362
|
-
import {
|
|
379
|
+
import { useAutocapture } from '@journium/react';
|
|
363
380
|
|
|
364
|
-
function
|
|
365
|
-
const {
|
|
366
|
-
const [
|
|
381
|
+
function ConsentBanner() {
|
|
382
|
+
const { startAutocapture, stopAutocapture } = useAutocapture();
|
|
383
|
+
const [hasConsent, setHasConsent] = useState(null);
|
|
384
|
+
|
|
385
|
+
useEffect(() => {
|
|
386
|
+
const savedConsent = localStorage.getItem('tracking_consent');
|
|
387
|
+
if (savedConsent === 'true') {
|
|
388
|
+
setHasConsent(true);
|
|
389
|
+
startAutocapture();
|
|
390
|
+
} else if (savedConsent === 'false') {
|
|
391
|
+
setHasConsent(false);
|
|
392
|
+
stopAutocapture();
|
|
393
|
+
}
|
|
394
|
+
}, [startAutocapture, stopAutocapture]);
|
|
367
395
|
|
|
368
396
|
const handleAccept = () => {
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
397
|
+
setHasConsent(true);
|
|
398
|
+
localStorage.setItem('tracking_consent', 'true');
|
|
399
|
+
startAutocapture();
|
|
372
400
|
};
|
|
373
401
|
|
|
374
402
|
const handleDecline = () => {
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
403
|
+
setHasConsent(false);
|
|
404
|
+
localStorage.setItem('tracking_consent', 'false');
|
|
405
|
+
stopAutocapture();
|
|
378
406
|
};
|
|
379
407
|
|
|
380
|
-
|
|
381
|
-
const consent = localStorage.getItem('journium_consent');
|
|
382
|
-
if (consent === 'false') {
|
|
383
|
-
stopAutoCapture();
|
|
384
|
-
setShowBanner(false);
|
|
385
|
-
} else if (consent === 'true') {
|
|
386
|
-
startAutoCapture();
|
|
387
|
-
setShowBanner(false);
|
|
388
|
-
}
|
|
389
|
-
}, [startAutoCapture, stopAutoCapture]);
|
|
390
|
-
|
|
391
|
-
if (!showBanner) return null;
|
|
408
|
+
if (hasConsent !== null) return null;
|
|
392
409
|
|
|
393
410
|
return (
|
|
394
|
-
<div className="
|
|
411
|
+
<div className="consent-banner">
|
|
395
412
|
<p>We use analytics to improve your experience.</p>
|
|
396
413
|
<button onClick={handleAccept}>Accept</button>
|
|
397
414
|
<button onClick={handleDecline}>Decline</button>
|
|
@@ -402,21 +419,20 @@ function PrivacyBanner() {
|
|
|
402
419
|
|
|
403
420
|
### Excluding Sensitive Data
|
|
404
421
|
|
|
422
|
+
Configure autocapture to ignore sensitive elements:
|
|
423
|
+
|
|
405
424
|
```jsx
|
|
406
425
|
<JourniumProvider
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
'input[type="password"]',
|
|
416
|
-
|
|
417
|
-
'.credit-card-input',
|
|
418
|
-
'[data-private]'
|
|
419
|
-
]
|
|
426
|
+
config={{
|
|
427
|
+
token: "your-token",
|
|
428
|
+
apiHost: "https://api.journium.com",
|
|
429
|
+
autocapture: {
|
|
430
|
+
captureClicks: true,
|
|
431
|
+
captureFormSubmits: true,
|
|
432
|
+
captureFormChanges: false,
|
|
433
|
+
ignoreClasses: ['no-track', 'sensitive', 'pii'],
|
|
434
|
+
ignoreElements: ['input[type="password"]', '.credit-card']
|
|
435
|
+
}
|
|
420
436
|
}}
|
|
421
437
|
>
|
|
422
438
|
<App />
|
|
@@ -428,84 +444,38 @@ function PrivacyBanner() {
|
|
|
428
444
|
Full TypeScript support with complete type definitions:
|
|
429
445
|
|
|
430
446
|
```typescript
|
|
431
|
-
import {
|
|
447
|
+
import { useTrackEvent, JourniumConfig } from '@journium/react';
|
|
432
448
|
|
|
433
|
-
interface
|
|
449
|
+
interface PurchaseEventProperties {
|
|
434
450
|
product_id: string;
|
|
435
451
|
category: string;
|
|
436
452
|
price: number;
|
|
453
|
+
currency: string;
|
|
437
454
|
}
|
|
438
455
|
|
|
439
456
|
function TypedComponent() {
|
|
440
|
-
const
|
|
457
|
+
const trackEvent = useTrackEvent();
|
|
441
458
|
|
|
442
|
-
const handlePurchase = () => {
|
|
459
|
+
const handlePurchase = (productData: PurchaseEventProperties) => {
|
|
443
460
|
// Fully typed event tracking
|
|
444
|
-
|
|
445
|
-
product_id: 'prod_123',
|
|
446
|
-
category: 'electronics',
|
|
447
|
-
price: 299.99
|
|
448
|
-
} as CustomEventProperties);
|
|
461
|
+
trackEvent('product_purchased', productData);
|
|
449
462
|
};
|
|
450
463
|
|
|
451
464
|
return <button onClick={handlePurchase}>Purchase</button>;
|
|
452
465
|
}
|
|
453
|
-
|
|
454
|
-
// Type-safe provider configuration
|
|
455
|
-
const config: JourniumConfig = {
|
|
456
|
-
token: 'your-token',
|
|
457
|
-
apiHost: 'https://api.journium.com',
|
|
458
|
-
autocapture: {
|
|
459
|
-
captureClicks: true,
|
|
460
|
-
captureFormSubmits: true,
|
|
461
|
-
ignoreClasses: ['no-track']
|
|
462
|
-
}
|
|
463
|
-
};
|
|
464
|
-
```
|
|
465
|
-
|
|
466
|
-
## ⚡ Performance Optimization
|
|
467
|
-
|
|
468
|
-
### Lazy Loading
|
|
469
|
-
|
|
470
|
-
```jsx
|
|
471
|
-
import { lazy, Suspense } from 'react';
|
|
472
|
-
|
|
473
|
-
const JourniumProvider = lazy(() => import('@journium/react').then(module => ({
|
|
474
|
-
default: module.JourniumProvider
|
|
475
|
-
})));
|
|
476
|
-
|
|
477
|
-
function App() {
|
|
478
|
-
return (
|
|
479
|
-
<Suspense fallback={<div>Loading...</div>}>
|
|
480
|
-
<JourniumProvider token="your-token" apiHost="https://api.journium.com">
|
|
481
|
-
<YourApp />
|
|
482
|
-
</JourniumProvider>
|
|
483
|
-
</Suspense>
|
|
484
|
-
);
|
|
485
|
-
}
|
|
486
466
|
```
|
|
487
467
|
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
track('action_2', { step: 2 });
|
|
500
|
-
track('action_3', { step: 3 });
|
|
501
|
-
|
|
502
|
-
// Force flush all queued events
|
|
503
|
-
await flush();
|
|
504
|
-
};
|
|
505
|
-
|
|
506
|
-
return <button onClick={handleMultipleActions}>Complete Flow</button>;
|
|
507
|
-
}
|
|
508
|
-
```
|
|
468
|
+
## 🔗 Available Hooks
|
|
469
|
+
|
|
470
|
+
| Hook | Purpose | Usage |
|
|
471
|
+
|------|---------|-------|
|
|
472
|
+
| `useTrackEvent()` | Track custom events | `trackEvent('event_name', properties)` |
|
|
473
|
+
| `useIdentify()` | Identify users on login/signup | `identify(distinctId, attributes)` |
|
|
474
|
+
| `useReset()` | Reset user identity on logout | `reset()` |
|
|
475
|
+
| `useTrackPageview()` | Manual pageview tracking | `trackPageview(properties)` |
|
|
476
|
+
| `useAutoTrackPageview(deps, props)` | Automatic pageview on mount | Auto-tracks when deps change |
|
|
477
|
+
| `useAutocapture()` | Control autocapture | `{ startAutocapture, stopAutocapture }` |
|
|
478
|
+
| `useJournium()` | Direct Journium instance access | Advanced use cases only |
|
|
509
479
|
|
|
510
480
|
## 🔗 Related Packages
|
|
511
481
|
|