@journium/react 1.0.0 → 1.0.2
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/context.d.ts +5 -4
- package/dist/context.d.ts.map +1 -1
- package/dist/hooks.d.ts +4 -6
- package/dist/hooks.d.ts.map +1 -1
- package/dist/index.d.ts +10 -10
- package/dist/index.d.ts.map +1 -1
- package/dist/index.esm.js +189 -198
- package/dist/index.esm.js.map +1 -1
- package/dist/index.js +189 -198
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/readme.md +229 -371
package/readme.md
CHANGED
|
@@ -8,17 +8,40 @@
|
|
|
8
8
|
|
|
9
9
|
The official React SDK for Journium providing hooks, providers, and components for seamless analytics integration in React applications.
|
|
10
10
|
|
|
11
|
-
##
|
|
12
|
-
|
|
13
|
-
### Installation
|
|
11
|
+
## Installation
|
|
14
12
|
|
|
13
|
+
### npm
|
|
15
14
|
```bash
|
|
16
15
|
npm install @journium/react
|
|
17
16
|
```
|
|
18
17
|
|
|
19
|
-
###
|
|
18
|
+
### pnpm
|
|
19
|
+
```bash
|
|
20
|
+
pnpm add @journium/react
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
### yarn
|
|
24
|
+
```bash
|
|
25
|
+
yarn add @journium/react
|
|
26
|
+
```
|
|
20
27
|
|
|
21
|
-
|
|
28
|
+
## Basic Setup
|
|
29
|
+
|
|
30
|
+
### Environment Variables
|
|
31
|
+
First, create a `.env.local` file in your project root:
|
|
32
|
+
|
|
33
|
+
**Note:** For CRA projects, use `REACT_APP_` prefix:
|
|
34
|
+
```env
|
|
35
|
+
REACT_APP_JOURNIUM_PUBLISHABLE_KEY=your-actual-publishable-key-here
|
|
36
|
+
```
|
|
37
|
+
|
|
38
|
+
**Note:** For Vite projects, use `VITE_` prefix:
|
|
39
|
+
```env
|
|
40
|
+
VITE_JOURNIUM_PUBLISHABLE_KEY=your-actual-publishable-key-here
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
### Initialize Journium
|
|
44
|
+
Wrap your app with the `JourniumProvider` to enable analytics throughout your React application.
|
|
22
45
|
|
|
23
46
|
```jsx
|
|
24
47
|
import React from 'react';
|
|
@@ -29,13 +52,8 @@ function Root() {
|
|
|
29
52
|
return (
|
|
30
53
|
<JourniumProvider
|
|
31
54
|
config={{
|
|
32
|
-
|
|
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
|
|
55
|
+
publishableKey: process.env.REACT_APP_JOURNIUM_PUBLISHABLE_KEY!
|
|
37
56
|
}}
|
|
38
|
-
autoCapture={true} // Enables auto-pageview and click tracking
|
|
39
57
|
>
|
|
40
58
|
<App />
|
|
41
59
|
</JourniumProvider>
|
|
@@ -45,9 +63,40 @@ function Root() {
|
|
|
45
63
|
export default Root;
|
|
46
64
|
```
|
|
47
65
|
|
|
48
|
-
|
|
66
|
+
**Vite Example:**
|
|
67
|
+
```jsx
|
|
68
|
+
// main.tsx
|
|
69
|
+
import React from 'react';
|
|
70
|
+
import ReactDOM from 'react-dom/client';
|
|
71
|
+
import { JourniumProvider } from '@journium/react';
|
|
72
|
+
import App from './App';
|
|
49
73
|
|
|
50
|
-
|
|
74
|
+
ReactDOM.createRoot(document.getElementById('root')!).render(
|
|
75
|
+
<React.StrictMode>
|
|
76
|
+
<JourniumProvider
|
|
77
|
+
config={{
|
|
78
|
+
publishableKey: import.meta.env.VITE_JOURNIUM_PUBLISHABLE_KEY!
|
|
79
|
+
}}
|
|
80
|
+
>
|
|
81
|
+
<App />
|
|
82
|
+
</JourniumProvider>
|
|
83
|
+
</React.StrictMode>
|
|
84
|
+
);
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
**Vite .env file:**
|
|
88
|
+
```env
|
|
89
|
+
VITE_JOURNIUM_PUBLISHABLE_KEY=your-actual-publishable-key-here
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
**For Next.js applications, use the dedicated [`@journium/nextjs`](../journium-nextjs) package instead.**
|
|
93
|
+
|
|
94
|
+
### API Classes and Types
|
|
95
|
+
|
|
96
|
+
The main analytics class is `JourniumAnalytics`, available through the React hooks and context.
|
|
97
|
+
|
|
98
|
+
### Track a Custom Event
|
|
99
|
+
Use the `useTrackEvent` hook to track custom events from any component.
|
|
51
100
|
|
|
52
101
|
```jsx
|
|
53
102
|
import React from 'react';
|
|
@@ -62,75 +111,29 @@ function SignupButton() {
|
|
|
62
111
|
source: 'landing_page',
|
|
63
112
|
plan: 'free'
|
|
64
113
|
});
|
|
65
|
-
// Your signup logic
|
|
66
114
|
};
|
|
67
115
|
|
|
68
116
|
return <button onClick={handleSignup}>Sign Up</button>;
|
|
69
117
|
}
|
|
70
118
|
```
|
|
71
119
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
### useTrackEvent - Track Custom Events
|
|
75
|
-
|
|
76
|
-
The primary hook for tracking custom business events:
|
|
77
|
-
|
|
78
|
-
```jsx
|
|
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
|
-
}
|
|
108
|
-
```
|
|
109
|
-
|
|
110
|
-
### useIdentify - User Identification
|
|
111
|
-
|
|
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.
|
|
120
|
+
### Identify a User
|
|
121
|
+
Use the `useIdentify` hook to identify users when they log in or sign up.
|
|
113
122
|
|
|
114
123
|
```jsx
|
|
124
|
+
import React from 'react';
|
|
115
125
|
import { useIdentify } from '@journium/react';
|
|
116
126
|
|
|
117
127
|
function LoginForm() {
|
|
118
128
|
const identify = useIdentify();
|
|
119
129
|
|
|
120
130
|
const handleLogin = async (email, password) => {
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
email: user.email,
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
// Redirect to dashboard or show success
|
|
131
|
-
} catch (error) {
|
|
132
|
-
// Handle login error
|
|
133
|
-
}
|
|
131
|
+
const user = await loginUser(email, password);
|
|
132
|
+
|
|
133
|
+
identify(user.id, {
|
|
134
|
+
name: user.name,
|
|
135
|
+
email: user.email
|
|
136
|
+
});
|
|
134
137
|
};
|
|
135
138
|
|
|
136
139
|
return (
|
|
@@ -141,370 +144,225 @@ function LoginForm() {
|
|
|
141
144
|
}
|
|
142
145
|
```
|
|
143
146
|
|
|
144
|
-
###
|
|
145
|
-
|
|
146
|
-
Use this hook to reset user identity when they log out:
|
|
147
|
+
### Reset User Identity
|
|
148
|
+
Use the `useReset` hook to reset user identity when they log out.
|
|
147
149
|
|
|
148
150
|
```jsx
|
|
151
|
+
import React from 'react';
|
|
149
152
|
import { useReset } from '@journium/react';
|
|
150
153
|
|
|
151
154
|
function LogoutButton() {
|
|
152
155
|
const reset = useReset();
|
|
153
156
|
|
|
154
157
|
const handleLogout = async () => {
|
|
155
|
-
|
|
156
|
-
|
|
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
|
|
164
|
-
}
|
|
158
|
+
await logoutUser();
|
|
159
|
+
reset();
|
|
165
160
|
};
|
|
166
161
|
|
|
167
162
|
return <button onClick={handleLogout}>Log Out</button>;
|
|
168
163
|
}
|
|
169
164
|
```
|
|
170
165
|
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
For tracking custom pageviews beyond automatic route tracking:
|
|
166
|
+
## Advanced Setup
|
|
167
|
+
You can override default configurations and control autocapture:
|
|
174
168
|
|
|
169
|
+
**React/CRA Example:**
|
|
175
170
|
```jsx
|
|
176
|
-
import
|
|
177
|
-
|
|
178
|
-
|
|
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
|
-
};
|
|
171
|
+
import React from 'react';
|
|
172
|
+
import { JourniumProvider } from '@journium/react';
|
|
173
|
+
import App from './App';
|
|
188
174
|
|
|
175
|
+
function Root() {
|
|
189
176
|
return (
|
|
190
|
-
<
|
|
191
|
-
|
|
192
|
-
|
|
177
|
+
<JourniumProvider
|
|
178
|
+
config={{
|
|
179
|
+
publishableKey: process.env.REACT_APP_JOURNIUM_PUBLISHABLE_KEY!,
|
|
180
|
+
apiHost: 'https://events.journium.app',
|
|
181
|
+
options: {
|
|
182
|
+
debug: process.env.REACT_APP_JOURNIUM_DEBUG === 'true',
|
|
183
|
+
flushAt: 5, // Send events after N events
|
|
184
|
+
flushInterval: 10000, // Send events every N milliseconds
|
|
185
|
+
sessionTimeout: 1800000, // Session timeout (30 minutes)
|
|
186
|
+
autoTrackPageviews: true, // Automatically track pageview events (default: true)
|
|
187
|
+
autocapture: { // Configure automatic event capture
|
|
188
|
+
captureClicks: true, // Track click events
|
|
189
|
+
captureFormSubmits: true, // Track form submissions
|
|
190
|
+
captureFormChanges: false, // Track form field changes
|
|
191
|
+
ignoreClasses: ['no-track', 'sensitive'], // CSS classes to ignore
|
|
192
|
+
ignoreElements: ['input[type="password"]'] // Elements to ignore
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
}}
|
|
196
|
+
>
|
|
197
|
+
<App />
|
|
198
|
+
</JourniumProvider>
|
|
193
199
|
);
|
|
194
200
|
}
|
|
195
|
-
```
|
|
196
201
|
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
Automatically track pageviews when components mount or dependencies change:
|
|
202
|
+
export default Root;
|
|
203
|
+
```
|
|
200
204
|
|
|
205
|
+
**Vite Example:**
|
|
201
206
|
```jsx
|
|
202
|
-
import
|
|
203
|
-
|
|
204
|
-
|
|
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
|
-
});
|
|
207
|
+
import React from 'react';
|
|
208
|
+
import { JourniumProvider } from '@journium/react';
|
|
209
|
+
import App from './App';
|
|
211
210
|
|
|
212
|
-
|
|
211
|
+
function Root() {
|
|
212
|
+
return (
|
|
213
|
+
<JourniumProvider
|
|
214
|
+
config={{
|
|
215
|
+
publishableKey: import.meta.env.VITE_JOURNIUM_PUBLISHABLE_KEY!,
|
|
216
|
+
apiHost: 'https://events.journium.app',
|
|
217
|
+
options: {
|
|
218
|
+
debug: import.meta.env.VITE_JOURNIUM_DEBUG === 'true',
|
|
219
|
+
flushAt: 5,
|
|
220
|
+
flushInterval: 10000,
|
|
221
|
+
sessionTimeout: 1800000,
|
|
222
|
+
autoTrackPageviews: true,
|
|
223
|
+
autocapture: {
|
|
224
|
+
captureClicks: true,
|
|
225
|
+
captureFormSubmits: true,
|
|
226
|
+
captureFormChanges: false,
|
|
227
|
+
ignoreClasses: ['no-track', 'sensitive'],
|
|
228
|
+
ignoreElements: ['input[type="password"]']
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
}}
|
|
232
|
+
>
|
|
233
|
+
<App />
|
|
234
|
+
</JourniumProvider>
|
|
235
|
+
);
|
|
213
236
|
}
|
|
214
237
|
|
|
215
|
-
|
|
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
|
-
}
|
|
238
|
+
export default Root;
|
|
225
239
|
```
|
|
226
240
|
|
|
227
|
-
##
|
|
241
|
+
## API Reference
|
|
228
242
|
|
|
229
|
-
###
|
|
243
|
+
### Components
|
|
230
244
|
|
|
231
|
-
|
|
245
|
+
#### `<JourniumProvider>`
|
|
246
|
+
Provider component that initializes Journium analytics throughout your React application.
|
|
232
247
|
|
|
233
|
-
|
|
234
|
-
|
|
248
|
+
**Props:**
|
|
249
|
+
- `config: JourniumConfig` - Configuration object for Journium
|
|
250
|
+
- `publishableKey: string` - Your Journium publishable key (required)
|
|
251
|
+
- `apiHost?: string` - Custom API endpoint (optional, defaults to 'https://events.journium.app')
|
|
252
|
+
- `options?: JourniumLocalOptions` - Local configuration options (optional)
|
|
253
|
+
- `children: ReactNode` - React children to wrap
|
|
235
254
|
|
|
236
|
-
|
|
237
|
-
const trackEvent = useTrackEvent();
|
|
255
|
+
### Hooks
|
|
238
256
|
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
trackEvent('form_submitted', {
|
|
243
|
-
form_name: 'contact',
|
|
244
|
-
form_type: 'lead_generation',
|
|
245
|
-
fields_completed: ['name', 'email', 'company']
|
|
246
|
-
});
|
|
247
|
-
|
|
248
|
-
// Submit form logic
|
|
249
|
-
};
|
|
257
|
+
#### `useTrackEvent()`
|
|
258
|
+
Returns a function to track custom events.
|
|
250
259
|
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
field_name: fieldName
|
|
255
|
-
});
|
|
256
|
-
};
|
|
260
|
+
**Returns:** `(event: string, properties?: Record<string, unknown>) => void`
|
|
261
|
+
- `event: string` - Event name to track
|
|
262
|
+
- `properties?: Record<string, unknown>` - Optional event properties
|
|
257
263
|
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
<input
|
|
261
|
-
name="email"
|
|
262
|
-
onChange={() => handleFieldChange('email')}
|
|
263
|
-
placeholder="Email"
|
|
264
|
-
/>
|
|
265
|
-
<input
|
|
266
|
-
name="company"
|
|
267
|
-
onChange={() => handleFieldChange('company')}
|
|
268
|
-
placeholder="Company"
|
|
269
|
-
/>
|
|
270
|
-
<button type="submit">Send Message</button>
|
|
271
|
-
</form>
|
|
272
|
-
);
|
|
273
|
-
}
|
|
274
|
-
```
|
|
264
|
+
#### `useIdentify()`
|
|
265
|
+
Returns a function to identify users.
|
|
275
266
|
|
|
276
|
-
|
|
267
|
+
**Returns:** `(distinctId: string, attributes?: Record<string, unknown>) => void`
|
|
268
|
+
- `distinctId: string` - Unique user identifier
|
|
269
|
+
- `attributes?: Record<string, unknown>` - Optional user attributes
|
|
277
270
|
|
|
278
|
-
|
|
271
|
+
#### `useReset()`
|
|
272
|
+
Returns a function to reset user identity (typically on logout).
|
|
279
273
|
|
|
280
|
-
|
|
281
|
-
import { useTrackEvent, useTrackPageview } from '@journium/react';
|
|
282
|
-
|
|
283
|
-
function OnboardingFlow({ step }) {
|
|
284
|
-
const trackEvent = useTrackEvent();
|
|
285
|
-
const trackPageview = useTrackPageview();
|
|
286
|
-
|
|
287
|
-
useEffect(() => {
|
|
288
|
-
// Track onboarding step pageview
|
|
289
|
-
trackPageview({
|
|
290
|
-
page_type: 'onboarding',
|
|
291
|
-
step: step,
|
|
292
|
-
flow: 'user_setup'
|
|
293
|
-
});
|
|
294
|
-
}, [step, trackPageview]);
|
|
295
|
-
|
|
296
|
-
const handleStepComplete = () => {
|
|
297
|
-
trackEvent('onboarding_step_completed', {
|
|
298
|
-
step: step,
|
|
299
|
-
time_spent: Date.now() - stepStartTime,
|
|
300
|
-
completed_successfully: true
|
|
301
|
-
});
|
|
302
|
-
};
|
|
274
|
+
**Returns:** `() => void`
|
|
303
275
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
step: step,
|
|
307
|
-
reason: 'user_choice'
|
|
308
|
-
});
|
|
309
|
-
};
|
|
276
|
+
#### `useTrackPageview()`
|
|
277
|
+
Returns a function to manually track pageview events.
|
|
310
278
|
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
<h2>Step {step}</h2>
|
|
314
|
-
<button onClick={handleStepComplete}>Complete Step</button>
|
|
315
|
-
<button onClick={handleSkipStep}>Skip</button>
|
|
316
|
-
</div>
|
|
317
|
-
);
|
|
318
|
-
}
|
|
319
|
-
```
|
|
279
|
+
**Returns:** `(properties?: Record<string, unknown>) => void`
|
|
280
|
+
- `properties?: Record<string, unknown>` - Optional pageview properties
|
|
320
281
|
|
|
321
|
-
|
|
282
|
+
#### `useAutoTrackPageview()`
|
|
283
|
+
Automatically tracks pageview when component mounts or dependencies change.
|
|
322
284
|
|
|
323
|
-
|
|
285
|
+
**Parameters:**
|
|
286
|
+
- `dependencies?: React.DependencyList` - Dependencies to watch for changes (defaults to empty array)
|
|
287
|
+
- `properties?: Record<string, unknown>` - Optional pageview properties
|
|
324
288
|
|
|
325
|
-
|
|
326
|
-
import { useTrackEvent } from '@journium/react';
|
|
289
|
+
**Returns:** `void`
|
|
327
290
|
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
const trackEvent = useTrackEvent();
|
|
291
|
+
#### `useAutocapture()`
|
|
292
|
+
Returns functions to control automatic event capture.
|
|
331
293
|
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
timestamp: new Date().toISOString(),
|
|
336
|
-
...context
|
|
337
|
-
});
|
|
338
|
-
};
|
|
294
|
+
**Returns:** `{ startAutocapture: () => void, stopAutocapture: () => void }`
|
|
295
|
+
- `startAutocapture()` - Enable automatic event capture
|
|
296
|
+
- `stopAutocapture()` - Disable automatic event capture
|
|
339
297
|
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
feature_name: featureName,
|
|
343
|
-
discovery_method: discoveryMethod
|
|
344
|
-
});
|
|
345
|
-
};
|
|
298
|
+
#### `useJournium()`
|
|
299
|
+
Returns the Journium context for advanced use cases.
|
|
346
300
|
|
|
347
|
-
|
|
348
|
-
|
|
301
|
+
**Returns:** `JourniumContextValue`
|
|
302
|
+
- `analytics: JourniumAnalytics | null` - The analytics instance
|
|
303
|
+
- `config: JourniumConfig | null` - The configuration object
|
|
304
|
+
- `effectiveOptions: JourniumLocalOptions | null` - The effective options (merged local and remote)
|
|
349
305
|
|
|
350
|
-
|
|
351
|
-
function AdvancedFeature() {
|
|
352
|
-
const { trackFeatureUsed, trackFeatureDiscovered } = useFeatureTracking();
|
|
306
|
+
### Types
|
|
353
307
|
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
search_type: 'filters',
|
|
357
|
-
filter_count: 3
|
|
358
|
-
});
|
|
359
|
-
};
|
|
308
|
+
#### `JourniumConfig`
|
|
309
|
+
Configuration object for initializing Journium.
|
|
360
310
|
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
</div>
|
|
367
|
-
);
|
|
311
|
+
```typescript
|
|
312
|
+
interface JourniumConfig {
|
|
313
|
+
publishableKey: string;
|
|
314
|
+
apiHost?: string;
|
|
315
|
+
options?: JourniumLocalOptions;
|
|
368
316
|
}
|
|
369
317
|
```
|
|
370
318
|
|
|
371
|
-
|
|
319
|
+
#### `JourniumLocalOptions`
|
|
320
|
+
Local configuration options that can be set on the client.
|
|
372
321
|
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
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]);
|
|
395
|
-
|
|
396
|
-
const handleAccept = () => {
|
|
397
|
-
setHasConsent(true);
|
|
398
|
-
localStorage.setItem('tracking_consent', 'true');
|
|
399
|
-
startAutocapture();
|
|
322
|
+
```typescript
|
|
323
|
+
interface JourniumLocalOptions {
|
|
324
|
+
debug?: boolean; // Enable debug logging
|
|
325
|
+
flushAt?: number; // Number of events before auto-flush
|
|
326
|
+
flushInterval?: number; // Flush interval in milliseconds
|
|
327
|
+
autocapture?: boolean | AutocaptureOptions; // Auto-capture configuration
|
|
328
|
+
autoTrackPageviews?: boolean; // Automatic pageview tracking
|
|
329
|
+
sessionTimeout?: number; // Session timeout in milliseconds
|
|
330
|
+
sampling?: {
|
|
331
|
+
enabled?: boolean;
|
|
332
|
+
rate?: number;
|
|
400
333
|
};
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
stopAutocapture();
|
|
334
|
+
features?: {
|
|
335
|
+
enableGeolocation?: boolean;
|
|
336
|
+
enableSessionRecording?: boolean;
|
|
337
|
+
enablePerformanceTracking?: boolean;
|
|
406
338
|
};
|
|
407
|
-
|
|
408
|
-
if (hasConsent !== null) return null;
|
|
409
|
-
|
|
410
|
-
return (
|
|
411
|
-
<div className="consent-banner">
|
|
412
|
-
<p>We use analytics to improve your experience.</p>
|
|
413
|
-
<button onClick={handleAccept}>Accept</button>
|
|
414
|
-
<button onClick={handleDecline}>Decline</button>
|
|
415
|
-
</div>
|
|
416
|
-
);
|
|
417
339
|
}
|
|
418
340
|
```
|
|
419
341
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
Configure autocapture to ignore sensitive elements:
|
|
423
|
-
|
|
424
|
-
```jsx
|
|
425
|
-
<JourniumProvider
|
|
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
|
-
}
|
|
436
|
-
}}
|
|
437
|
-
>
|
|
438
|
-
<App />
|
|
439
|
-
</JourniumProvider>
|
|
440
|
-
```
|
|
441
|
-
|
|
442
|
-
## 📱 TypeScript Support
|
|
443
|
-
|
|
444
|
-
Full TypeScript support with complete type definitions:
|
|
342
|
+
#### `AutocaptureOptions`
|
|
343
|
+
Configuration for automatic event capture.
|
|
445
344
|
|
|
446
345
|
```typescript
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
function TypedComponent() {
|
|
457
|
-
const trackEvent = useTrackEvent();
|
|
458
|
-
|
|
459
|
-
const handlePurchase = (productData: PurchaseEventProperties) => {
|
|
460
|
-
// Fully typed event tracking
|
|
461
|
-
trackEvent('product_purchased', productData);
|
|
462
|
-
};
|
|
463
|
-
|
|
464
|
-
return <button onClick={handlePurchase}>Purchase</button>;
|
|
346
|
+
interface AutocaptureOptions {
|
|
347
|
+
captureClicks?: boolean; // Capture click events
|
|
348
|
+
captureFormSubmits?: boolean; // Capture form submissions
|
|
349
|
+
captureFormChanges?: boolean; // Capture form field changes
|
|
350
|
+
captureTextSelection?: boolean; // Capture text selection events
|
|
351
|
+
ignoreClasses?: string[]; // CSS classes to ignore
|
|
352
|
+
ignoreElements?: string[]; // HTML elements to ignore
|
|
353
|
+
captureContentText?: boolean; // Capture element text content
|
|
465
354
|
}
|
|
466
355
|
```
|
|
467
356
|
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
## 🔗 Related Packages
|
|
481
|
-
|
|
482
|
-
Part of the Journium JavaScript SDK ecosystem:
|
|
483
|
-
|
|
484
|
-
- **[journium-js](https://npmjs.com/package/journium-js)** - Core JavaScript SDK for web browsers
|
|
485
|
-
- **[@journium/nextjs](https://npmjs.com/package/@journium/nextjs)** - Next.js integration with SSR support
|
|
486
|
-
- **[@journium/node](https://npmjs.com/package/@journium/node)** - Node.js server-side tracking
|
|
487
|
-
- **[@journium/core](https://npmjs.com/package/@journium/core)** - Core utilities and types
|
|
488
|
-
|
|
489
|
-
## 📖 Documentation
|
|
490
|
-
|
|
491
|
-
For complete documentation, guides, and examples:
|
|
492
|
-
|
|
493
|
-
- **[Documentation](https://docs.journium.app)** - Complete guides and API reference
|
|
494
|
-
- **[React Guide](https://docs.journium.app/react)** - React-specific documentation
|
|
495
|
-
- **[Examples](https://docs.journium.app/examples/react)** - React code examples and patterns
|
|
496
|
-
|
|
497
|
-
## 🤝 Contributing
|
|
498
|
-
|
|
499
|
-
We welcome contributions! Please see our [Contributing Guide](https://github.com/journium/journium-js/blob/main/CONTRIBUTING.md).
|
|
500
|
-
|
|
501
|
-
## 📄 License
|
|
502
|
-
|
|
503
|
-
MIT License - see [LICENSE](https://github.com/journium/journium-js/blob/main/LICENSE) file for details.
|
|
504
|
-
|
|
505
|
-
## 🆘 Support
|
|
506
|
-
|
|
507
|
-
- **📚 Docs**: [docs.journium.app](https://docs.journium.app)
|
|
508
|
-
- **🐛 Issues**: [GitHub Issues](https://github.com/journium/journium-js/issues)
|
|
509
|
-
- **💬 Discussions**: [GitHub Discussions](https://github.com/journium/journium-js/discussions)
|
|
510
|
-
- **📧 Email**: support@journium.com
|
|
357
|
+
#### `JourniumAnalytics`
|
|
358
|
+
The main analytics class instance available through hooks.
|
|
359
|
+
|
|
360
|
+
**Methods:**
|
|
361
|
+
- `track(event: string, properties?: Record<string, unknown>): void` - Track custom event
|
|
362
|
+
- `identify(distinctId: string, attributes?: Record<string, unknown>): void` - Identify user
|
|
363
|
+
- `reset(): void` - Reset user identity
|
|
364
|
+
- `capturePageview(properties?: Record<string, unknown>): void` - Track pageview
|
|
365
|
+
- `startAutocapture(): void` - Start automatic event capture
|
|
366
|
+
- `stopAutocapture(): void` - Stop automatic event capture
|
|
367
|
+
- `flush(): void` - Flush pending events immediately
|
|
368
|
+
- `getEffectiveOptions(): JourniumLocalOptions` - Get effective configuration
|