@datalyr/react-native 1.1.1 → 1.2.0
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/CHANGELOG.md +24 -141
- package/LICENSE +21 -0
- package/README.md +405 -217
- package/datalyr-react-native.podspec +31 -0
- package/ios/DatalyrNative.m +70 -0
- package/ios/DatalyrNative.swift +275 -0
- package/ios/DatalyrSKAdNetwork.m +26 -0
- package/lib/datalyr-sdk.d.ts +64 -3
- package/lib/datalyr-sdk.js +322 -3
- package/lib/index.d.ts +1 -0
- package/lib/index.js +4 -2
- package/lib/integrations/index.d.ts +6 -0
- package/lib/integrations/index.js +6 -0
- package/lib/integrations/meta-integration.d.ts +76 -0
- package/lib/integrations/meta-integration.js +218 -0
- package/lib/integrations/tiktok-integration.d.ts +82 -0
- package/lib/integrations/tiktok-integration.js +356 -0
- package/lib/native/DatalyrNativeBridge.d.ts +31 -0
- package/lib/native/DatalyrNativeBridge.js +168 -0
- package/lib/native/index.d.ts +5 -0
- package/lib/native/index.js +5 -0
- package/lib/types.d.ts +29 -0
- package/package.json +10 -5
- package/src/datalyr-sdk-expo.ts +957 -0
- package/src/datalyr-sdk.ts +419 -19
- package/src/expo.ts +38 -18
- package/src/index.ts +5 -2
- package/src/integrations/index.ts +7 -0
- package/src/integrations/meta-integration.ts +238 -0
- package/src/integrations/tiktok-integration.ts +360 -0
- package/src/native/DatalyrNativeBridge.ts +271 -0
- package/src/native/index.ts +11 -0
- package/src/types.ts +39 -0
- package/src/utils-expo.ts +25 -3
- package/src/utils-interface.ts +38 -0
- package/EXPO_INSTALL.md +0 -297
- package/INSTALL.md +0 -402
- package/examples/attribution-example.tsx +0 -377
- package/examples/auto-events-example.tsx +0 -403
- package/examples/example.tsx +0 -250
- package/examples/skadnetwork-example.tsx +0 -380
- package/examples/test-implementation.tsx +0 -163
package/README.md
CHANGED
|
@@ -1,27 +1,39 @@
|
|
|
1
1
|
# @datalyr/react-native
|
|
2
2
|
|
|
3
|
-
|
|
3
|
+
Mobile analytics and attribution SDK for React Native and Expo. Track events, identify users, and capture attribution data from ad platforms.
|
|
4
|
+
|
|
5
|
+
## Table of Contents
|
|
6
|
+
|
|
7
|
+
- [Installation](#installation)
|
|
8
|
+
- [Quick Start](#quick-start)
|
|
9
|
+
- [How It Works](#how-it-works)
|
|
10
|
+
- [Configuration](#configuration)
|
|
11
|
+
- [Event Tracking](#event-tracking)
|
|
12
|
+
- [Custom Events](#custom-events)
|
|
13
|
+
- [Screen Views](#screen-views)
|
|
14
|
+
- [E-Commerce Events](#e-commerce-events)
|
|
15
|
+
- [User Identity](#user-identity)
|
|
16
|
+
- [Anonymous ID](#anonymous-id)
|
|
17
|
+
- [Identifying Users](#identifying-users)
|
|
18
|
+
- [User Properties](#user-properties)
|
|
19
|
+
- [Attribution](#attribution)
|
|
20
|
+
- [Automatic Capture](#automatic-capture)
|
|
21
|
+
- [Deferred Deep Links](#deferred-deep-links)
|
|
22
|
+
- [Event Queue](#event-queue)
|
|
23
|
+
- [Auto Events](#auto-events)
|
|
24
|
+
- [SKAdNetwork](#skadnetwork)
|
|
25
|
+
- [Platform Integrations](#platform-integrations)
|
|
26
|
+
- [Expo Support](#expo-support)
|
|
27
|
+
- [TypeScript](#typescript)
|
|
28
|
+
- [Troubleshooting](#troubleshooting)
|
|
29
|
+
- [License](#license)
|
|
4
30
|
|
|
5
|
-
|
|
6
|
-
[](https://opensource.org/licenses/MIT)
|
|
7
|
-
|
|
8
|
-
## Features
|
|
9
|
-
|
|
10
|
-
- 🎯 **Complete Attribution** - Track users from ad click to conversion
|
|
11
|
-
- 📱 **React Native & Expo** - Works with both platforms
|
|
12
|
-
- 🔄 **Automatic Events** - Session tracking, screen views, app lifecycle
|
|
13
|
-
- 📊 **SKAdNetwork** - iOS 14+ attribution support
|
|
14
|
-
- 💾 **Offline Support** - Events saved and retried when reconnected
|
|
15
|
-
- 🔒 **Privacy First** - GDPR/CCPA compliant
|
|
16
|
-
- ⚡ **Lightweight** - < 100KB, minimal battery impact
|
|
17
|
-
- 🆔 **Identity Resolution** - Persistent anonymous ID links web → mobile → server events
|
|
31
|
+
---
|
|
18
32
|
|
|
19
33
|
## Installation
|
|
20
34
|
|
|
21
35
|
```bash
|
|
22
36
|
npm install @datalyr/react-native
|
|
23
|
-
# or
|
|
24
|
-
yarn add @datalyr/react-native
|
|
25
37
|
```
|
|
26
38
|
|
|
27
39
|
### iOS Setup
|
|
@@ -30,333 +42,509 @@ yarn add @datalyr/react-native
|
|
|
30
42
|
cd ios && pod install
|
|
31
43
|
```
|
|
32
44
|
|
|
33
|
-
|
|
45
|
+
This installs the SDK with bundled Meta and TikTok native SDKs.
|
|
46
|
+
|
|
47
|
+
Add to `ios/YourApp/Info.plist`:
|
|
48
|
+
|
|
49
|
+
```xml
|
|
50
|
+
<!-- Meta SDK -->
|
|
51
|
+
<key>FacebookAppID</key>
|
|
52
|
+
<string>YOUR_FACEBOOK_APP_ID</string>
|
|
53
|
+
<key>FacebookClientToken</key>
|
|
54
|
+
<string>YOUR_CLIENT_TOKEN</string>
|
|
55
|
+
<key>FacebookDisplayName</key>
|
|
56
|
+
<string>Your App Name</string>
|
|
57
|
+
|
|
58
|
+
<key>CFBundleURLTypes</key>
|
|
59
|
+
<array>
|
|
60
|
+
<dict>
|
|
61
|
+
<key>CFBundleURLSchemes</key>
|
|
62
|
+
<array>
|
|
63
|
+
<string>fbYOUR_FACEBOOK_APP_ID</string>
|
|
64
|
+
</array>
|
|
65
|
+
</dict>
|
|
66
|
+
</array>
|
|
67
|
+
|
|
68
|
+
<!-- TikTok SDK -->
|
|
69
|
+
<key>LSApplicationQueriesSchemes</key>
|
|
70
|
+
<array>
|
|
71
|
+
<string>tiktok</string>
|
|
72
|
+
<string>snssdk1180</string>
|
|
73
|
+
<string>snssdk1233</string>
|
|
74
|
+
</array>
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
### Android Setup
|
|
34
78
|
|
|
35
|
-
|
|
79
|
+
No additional setup required.
|
|
80
|
+
|
|
81
|
+
---
|
|
36
82
|
|
|
37
83
|
## Quick Start
|
|
38
84
|
|
|
39
85
|
```typescript
|
|
40
86
|
import { Datalyr } from '@datalyr/react-native';
|
|
41
87
|
|
|
42
|
-
// Initialize
|
|
88
|
+
// Initialize
|
|
43
89
|
await Datalyr.initialize({
|
|
44
|
-
apiKey: 'dk_your_api_key',
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
enableAttribution: true, // Track attribution data from ads
|
|
90
|
+
apiKey: 'dk_your_api_key',
|
|
91
|
+
enableAutoEvents: true,
|
|
92
|
+
enableAttribution: true,
|
|
48
93
|
});
|
|
49
94
|
|
|
50
|
-
// Track
|
|
51
|
-
await Datalyr.track('
|
|
52
|
-
button_name: 'purchase',
|
|
53
|
-
value: 99.99,
|
|
54
|
-
});
|
|
95
|
+
// Track events
|
|
96
|
+
await Datalyr.track('button_clicked', { button: 'signup' });
|
|
55
97
|
|
|
56
|
-
// Identify
|
|
57
|
-
await Datalyr.identify('user_123', {
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
98
|
+
// Identify users
|
|
99
|
+
await Datalyr.identify('user_123', { email: 'user@example.com' });
|
|
100
|
+
|
|
101
|
+
// Track purchases
|
|
102
|
+
await Datalyr.trackPurchase(99.99, 'USD', 'product_123');
|
|
61
103
|
```
|
|
62
104
|
|
|
63
|
-
|
|
105
|
+
---
|
|
106
|
+
|
|
107
|
+
## How It Works
|
|
108
|
+
|
|
109
|
+
The SDK collects events and sends them to the Datalyr backend for analytics and attribution.
|
|
110
|
+
|
|
111
|
+
### Data Flow
|
|
112
|
+
|
|
113
|
+
1. Events are created with `track()`, `screen()`, or e-commerce methods
|
|
114
|
+
2. Each event includes device info, session data, and attribution parameters
|
|
115
|
+
3. Events are queued locally and sent in batches
|
|
116
|
+
4. If offline, events are stored and sent when connectivity returns
|
|
117
|
+
5. Events are processed server-side for analytics and attribution reporting
|
|
118
|
+
|
|
119
|
+
### Event Payload
|
|
120
|
+
|
|
121
|
+
Every event includes:
|
|
64
122
|
|
|
65
123
|
```typescript
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
124
|
+
{
|
|
125
|
+
event: 'purchase', // Event name
|
|
126
|
+
properties: { ... }, // Custom properties
|
|
127
|
+
|
|
128
|
+
// Identity
|
|
129
|
+
anonymous_id: 'uuid', // Persistent device ID
|
|
130
|
+
user_id: 'user_123', // Set after identify()
|
|
131
|
+
session_id: 'uuid', // Current session
|
|
132
|
+
|
|
133
|
+
// Device
|
|
134
|
+
platform: 'ios',
|
|
135
|
+
device_model: 'iPhone 14',
|
|
136
|
+
os_version: '17.0',
|
|
137
|
+
app_version: '1.2.0',
|
|
138
|
+
|
|
139
|
+
// Attribution (if captured)
|
|
140
|
+
utm_source: 'facebook',
|
|
141
|
+
fbclid: 'abc123',
|
|
142
|
+
|
|
143
|
+
// Timestamps
|
|
144
|
+
timestamp: '2024-01-15T10:30:00Z',
|
|
77
145
|
}
|
|
78
146
|
```
|
|
79
147
|
|
|
80
|
-
|
|
148
|
+
---
|
|
149
|
+
|
|
150
|
+
## Configuration
|
|
81
151
|
|
|
82
|
-
### Initialize
|
|
83
152
|
```typescript
|
|
84
153
|
await Datalyr.initialize({
|
|
85
|
-
|
|
86
|
-
|
|
154
|
+
// Required
|
|
155
|
+
apiKey: string,
|
|
156
|
+
|
|
157
|
+
// Features
|
|
158
|
+
debug?: boolean, // Console logging
|
|
159
|
+
enableAutoEvents?: boolean, // Track app lifecycle
|
|
160
|
+
enableAttribution?: boolean, // Capture attribution data
|
|
161
|
+
|
|
162
|
+
// Event Queue
|
|
163
|
+
batchSize?: number, // Events per batch (default: 10)
|
|
164
|
+
flushInterval?: number, // Send interval ms (default: 30000)
|
|
165
|
+
maxQueueSize?: number, // Max queued events (default: 100)
|
|
166
|
+
|
|
167
|
+
// iOS
|
|
168
|
+
skadTemplate?: 'ecommerce' | 'gaming' | 'subscription',
|
|
169
|
+
|
|
170
|
+
// Platform SDKs
|
|
171
|
+
meta?: MetaConfig,
|
|
172
|
+
tiktok?: TikTokConfig,
|
|
87
173
|
});
|
|
88
174
|
```
|
|
89
175
|
|
|
90
|
-
|
|
176
|
+
---
|
|
177
|
+
|
|
178
|
+
## Event Tracking
|
|
179
|
+
|
|
180
|
+
### Custom Events
|
|
181
|
+
|
|
182
|
+
Track any action in your app:
|
|
183
|
+
|
|
91
184
|
```typescript
|
|
92
185
|
// Simple event
|
|
93
|
-
await Datalyr.track('
|
|
186
|
+
await Datalyr.track('signup_started');
|
|
94
187
|
|
|
95
188
|
// Event with properties
|
|
96
|
-
await Datalyr.track('
|
|
189
|
+
await Datalyr.track('product_viewed', {
|
|
97
190
|
product_id: 'SKU123',
|
|
98
|
-
|
|
191
|
+
product_name: 'Blue Shirt',
|
|
192
|
+
price: 29.99,
|
|
99
193
|
currency: 'USD',
|
|
194
|
+
category: 'Apparel',
|
|
100
195
|
});
|
|
101
|
-
```
|
|
102
196
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
plan: 'premium',
|
|
109
|
-
company: 'Acme Inc',
|
|
197
|
+
// Event with value
|
|
198
|
+
await Datalyr.track('level_completed', {
|
|
199
|
+
level: 5,
|
|
200
|
+
score: 1250,
|
|
201
|
+
time_seconds: 120,
|
|
110
202
|
});
|
|
111
203
|
```
|
|
112
204
|
|
|
113
|
-
###
|
|
205
|
+
### Screen Views
|
|
206
|
+
|
|
207
|
+
Track navigation:
|
|
208
|
+
|
|
114
209
|
```typescript
|
|
210
|
+
await Datalyr.screen('Home');
|
|
211
|
+
|
|
115
212
|
await Datalyr.screen('Product Details', {
|
|
116
213
|
product_id: 'SKU123',
|
|
117
|
-
|
|
214
|
+
source: 'search',
|
|
118
215
|
});
|
|
119
216
|
```
|
|
120
217
|
|
|
121
|
-
###
|
|
218
|
+
### E-Commerce Events
|
|
219
|
+
|
|
220
|
+
Standard e-commerce events that also forward to Meta and TikTok:
|
|
221
|
+
|
|
122
222
|
```typescript
|
|
123
|
-
//
|
|
124
|
-
await Datalyr.
|
|
223
|
+
// View product
|
|
224
|
+
await Datalyr.trackViewContent('SKU123', 'Blue Shirt', 'product', 29.99, 'USD');
|
|
225
|
+
|
|
226
|
+
// Add to cart
|
|
227
|
+
await Datalyr.trackAddToCart(29.99, 'USD', 'SKU123', 'Blue Shirt');
|
|
228
|
+
|
|
229
|
+
// Start checkout
|
|
230
|
+
await Datalyr.trackInitiateCheckout(59.98, 'USD', 2, ['SKU123', 'SKU456']);
|
|
125
231
|
|
|
126
|
-
//
|
|
232
|
+
// Complete purchase
|
|
233
|
+
await Datalyr.trackPurchase(59.98, 'USD', 'order_123');
|
|
234
|
+
|
|
235
|
+
// Subscription
|
|
127
236
|
await Datalyr.trackSubscription(9.99, 'USD', 'monthly_pro');
|
|
128
237
|
|
|
129
|
-
//
|
|
130
|
-
await Datalyr.
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
238
|
+
// Registration
|
|
239
|
+
await Datalyr.trackCompleteRegistration('email');
|
|
240
|
+
|
|
241
|
+
// Search
|
|
242
|
+
await Datalyr.trackSearch('blue shoes', ['SKU1', 'SKU2']);
|
|
243
|
+
|
|
244
|
+
// Lead
|
|
245
|
+
await Datalyr.trackLead(100.0, 'USD');
|
|
246
|
+
|
|
247
|
+
// Payment info
|
|
248
|
+
await Datalyr.trackAddPaymentInfo(true);
|
|
135
249
|
```
|
|
136
250
|
|
|
137
|
-
|
|
251
|
+
---
|
|
252
|
+
|
|
253
|
+
## User Identity
|
|
254
|
+
|
|
255
|
+
### Anonymous ID
|
|
138
256
|
|
|
139
|
-
|
|
140
|
-
- Deep links and Universal Links
|
|
141
|
-
- UTM parameters
|
|
142
|
-
- Referrer data
|
|
143
|
-
- Install attribution
|
|
144
|
-
- Platform click IDs (fbclid, gclid, ttclid, etc.)
|
|
257
|
+
Every device gets a persistent anonymous ID on first launch:
|
|
145
258
|
|
|
146
|
-
### Get Attribution Data
|
|
147
259
|
```typescript
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
// {
|
|
151
|
-
// campaign: 'summer_sale',
|
|
152
|
-
// source: 'facebook',
|
|
153
|
-
// medium: 'social',
|
|
154
|
-
// fbclid: 'abc123',
|
|
155
|
-
// ...
|
|
156
|
-
// }
|
|
260
|
+
const anonymousId = Datalyr.getAnonymousId();
|
|
261
|
+
// 'a1b2c3d4-e5f6-7890-abcd-ef1234567890'
|
|
157
262
|
```
|
|
158
263
|
|
|
159
|
-
|
|
264
|
+
This ID:
|
|
265
|
+
- Persists across app sessions
|
|
266
|
+
- Links events before and after user identification
|
|
267
|
+
- Can be passed to your backend for server-side attribution
|
|
268
|
+
|
|
269
|
+
### Identifying Users
|
|
270
|
+
|
|
271
|
+
Link the anonymous ID to a known user:
|
|
272
|
+
|
|
160
273
|
```typescript
|
|
161
|
-
await Datalyr.
|
|
162
|
-
|
|
163
|
-
source: 'newsletter',
|
|
164
|
-
medium: 'email',
|
|
274
|
+
await Datalyr.identify('user_123', {
|
|
275
|
+
email: 'user@example.com',
|
|
165
276
|
});
|
|
166
277
|
```
|
|
167
278
|
|
|
168
|
-
|
|
279
|
+
After `identify()`:
|
|
280
|
+
- All future events include `user_id`
|
|
281
|
+
- Historical anonymous events can be linked server-side
|
|
282
|
+
- User data is forwarded to Meta/TikTok for Advanced Matching
|
|
169
283
|
|
|
170
|
-
|
|
284
|
+
### User Properties
|
|
285
|
+
|
|
286
|
+
Pass any user attributes:
|
|
171
287
|
|
|
172
288
|
```typescript
|
|
173
|
-
|
|
174
|
-
|
|
289
|
+
await Datalyr.identify('user_123', {
|
|
290
|
+
// Standard fields
|
|
291
|
+
email: 'user@example.com',
|
|
292
|
+
name: 'John Doe',
|
|
293
|
+
phone: '+1234567890',
|
|
175
294
|
|
|
176
|
-
//
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
items: cart,
|
|
181
|
-
anonymous_id: anonymousId // Links server events to mobile events
|
|
182
|
-
})
|
|
295
|
+
// Custom fields
|
|
296
|
+
plan: 'premium',
|
|
297
|
+
company: 'Acme Inc',
|
|
298
|
+
signup_date: '2024-01-15',
|
|
183
299
|
});
|
|
300
|
+
```
|
|
184
301
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
302
|
+
### Logout
|
|
303
|
+
|
|
304
|
+
Clear user data on logout:
|
|
305
|
+
|
|
306
|
+
```typescript
|
|
307
|
+
await Datalyr.reset();
|
|
190
308
|
```
|
|
191
309
|
|
|
192
|
-
|
|
193
|
-
-
|
|
194
|
-
-
|
|
195
|
-
-
|
|
310
|
+
This:
|
|
311
|
+
- Clears the user ID
|
|
312
|
+
- Starts a new session
|
|
313
|
+
- Keeps the anonymous ID (same device)
|
|
196
314
|
|
|
197
|
-
|
|
315
|
+
---
|
|
198
316
|
|
|
199
|
-
|
|
317
|
+
## Attribution
|
|
200
318
|
|
|
201
|
-
|
|
202
|
-
// Get current session
|
|
203
|
-
const session = Datalyr.getCurrentSession();
|
|
319
|
+
### Automatic Capture
|
|
204
320
|
|
|
205
|
-
|
|
206
|
-
await Datalyr.endSession();
|
|
321
|
+
The SDK captures attribution from deep links and referrers:
|
|
207
322
|
|
|
208
|
-
|
|
209
|
-
|
|
323
|
+
```typescript
|
|
324
|
+
const attribution = Datalyr.getAttributionData();
|
|
210
325
|
```
|
|
211
326
|
|
|
212
|
-
|
|
327
|
+
Captured parameters:
|
|
328
|
+
|
|
329
|
+
| Type | Parameters |
|
|
330
|
+
|------|------------|
|
|
331
|
+
| UTM | `utm_source`, `utm_medium`, `utm_campaign`, `utm_content`, `utm_term` |
|
|
332
|
+
| Click IDs | `fbclid`, `gclid`, `ttclid`, `twclid`, `li_click_id`, `msclkid` |
|
|
333
|
+
| Campaign | `campaign_id`, `adset_id`, `ad_id` |
|
|
334
|
+
|
|
335
|
+
### Deferred Deep Links
|
|
213
336
|
|
|
214
|
-
|
|
337
|
+
Capture attribution from App Store installs (iOS):
|
|
215
338
|
|
|
216
339
|
```typescript
|
|
217
340
|
await Datalyr.initialize({
|
|
218
341
|
apiKey: 'dk_your_api_key',
|
|
219
|
-
|
|
342
|
+
meta: {
|
|
343
|
+
appId: '1234567890',
|
|
344
|
+
enableDeferredDeepLink: true,
|
|
345
|
+
},
|
|
220
346
|
});
|
|
221
347
|
|
|
222
|
-
//
|
|
223
|
-
|
|
348
|
+
// Check for deferred attribution
|
|
349
|
+
const deferred = Datalyr.getDeferredAttributionData();
|
|
350
|
+
if (deferred) {
|
|
351
|
+
console.log(deferred.fbclid); // Facebook click ID
|
|
352
|
+
console.log(deferred.campaignId); // Campaign ID
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
### Manual Attribution
|
|
357
|
+
|
|
358
|
+
Set attribution programmatically:
|
|
224
359
|
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
360
|
+
```typescript
|
|
361
|
+
await Datalyr.setAttributionData({
|
|
362
|
+
utm_source: 'newsletter',
|
|
363
|
+
utm_campaign: 'spring_sale',
|
|
364
|
+
});
|
|
228
365
|
```
|
|
229
366
|
|
|
230
|
-
|
|
367
|
+
---
|
|
368
|
+
|
|
369
|
+
## Event Queue
|
|
231
370
|
|
|
232
|
-
|
|
371
|
+
Events are batched for efficiency and offline support.
|
|
233
372
|
|
|
234
|
-
|
|
235
|
-
- `app_open` - App launches
|
|
236
|
-
- `app_background` - App enters background
|
|
237
|
-
- `app_foreground` - App returns to foreground
|
|
238
|
-
- `app_update` - App version changes
|
|
239
|
-
- `session_start` - New session begins
|
|
240
|
-
- `session_end` - Session expires
|
|
373
|
+
### Configuration
|
|
241
374
|
|
|
242
|
-
|
|
375
|
+
```typescript
|
|
376
|
+
await Datalyr.initialize({
|
|
377
|
+
apiKey: 'dk_your_api_key',
|
|
378
|
+
batchSize: 10, // Send when 10 events queued
|
|
379
|
+
flushInterval: 30000, // Or every 30 seconds
|
|
380
|
+
maxQueueSize: 100, // Max events to store offline
|
|
381
|
+
});
|
|
382
|
+
```
|
|
243
383
|
|
|
244
|
-
|
|
384
|
+
### Manual Flush
|
|
385
|
+
|
|
386
|
+
Send all queued events immediately:
|
|
245
387
|
|
|
246
388
|
```typescript
|
|
247
|
-
// Manually flush queue
|
|
248
389
|
await Datalyr.flush();
|
|
390
|
+
```
|
|
391
|
+
|
|
392
|
+
### Queue Status
|
|
249
393
|
|
|
250
|
-
|
|
394
|
+
```typescript
|
|
251
395
|
const status = Datalyr.getStatus();
|
|
252
|
-
console.log(
|
|
396
|
+
console.log(status.queueStats.queueSize); // Events waiting
|
|
397
|
+
console.log(status.queueStats.pending); // Events being sent
|
|
253
398
|
```
|
|
254
399
|
|
|
255
|
-
|
|
400
|
+
### Offline Support
|
|
401
|
+
|
|
402
|
+
When the device is offline:
|
|
403
|
+
- Events are stored locally
|
|
404
|
+
- Queue persists across app restarts
|
|
405
|
+
- Events are sent when connectivity returns
|
|
256
406
|
|
|
257
|
-
|
|
407
|
+
---
|
|
408
|
+
|
|
409
|
+
## Auto Events
|
|
410
|
+
|
|
411
|
+
Enable automatic lifecycle tracking:
|
|
258
412
|
|
|
259
413
|
```typescript
|
|
260
414
|
await Datalyr.initialize({
|
|
261
415
|
apiKey: 'dk_your_api_key',
|
|
262
|
-
|
|
416
|
+
enableAutoEvents: true,
|
|
263
417
|
});
|
|
264
418
|
```
|
|
265
419
|
|
|
266
|
-
|
|
420
|
+
| Event | Trigger |
|
|
421
|
+
|-------|---------|
|
|
422
|
+
| `app_install` | First app open |
|
|
423
|
+
| `app_open` | App launch |
|
|
424
|
+
| `app_background` | App enters background |
|
|
425
|
+
| `app_foreground` | App returns to foreground |
|
|
426
|
+
| `app_update` | App version changes |
|
|
427
|
+
| `session_start` | New session begins |
|
|
428
|
+
| `session_end` | Session expires (30 min inactivity) |
|
|
429
|
+
|
|
430
|
+
---
|
|
431
|
+
|
|
432
|
+
## SKAdNetwork
|
|
267
433
|
|
|
268
|
-
|
|
434
|
+
iOS conversion tracking with Apple's SKAdNetwork:
|
|
269
435
|
|
|
270
436
|
```typescript
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
437
|
+
await Datalyr.initialize({
|
|
438
|
+
apiKey: 'dk_your_api_key',
|
|
439
|
+
skadTemplate: 'ecommerce',
|
|
440
|
+
});
|
|
441
|
+
|
|
442
|
+
// E-commerce events update conversion values
|
|
443
|
+
await Datalyr.trackPurchase(99.99, 'USD');
|
|
278
444
|
```
|
|
279
445
|
|
|
280
|
-
|
|
446
|
+
| Template | Events |
|
|
447
|
+
|----------|--------|
|
|
448
|
+
| `ecommerce` | purchase, add_to_cart, begin_checkout, signup, subscribe, view_item |
|
|
449
|
+
| `gaming` | level_complete, tutorial_complete, purchase, achievement_unlocked |
|
|
450
|
+
| `subscription` | trial_start, subscribe, upgrade, cancel, signup |
|
|
281
451
|
|
|
282
|
-
|
|
452
|
+
---
|
|
453
|
+
|
|
454
|
+
## Platform Integrations
|
|
455
|
+
|
|
456
|
+
Bundled Meta and TikTok SDKs for iOS. No extra npm packages needed.
|
|
457
|
+
|
|
458
|
+
### Meta (Facebook)
|
|
283
459
|
|
|
284
460
|
```typescript
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
461
|
+
await Datalyr.initialize({
|
|
462
|
+
apiKey: 'dk_your_api_key',
|
|
463
|
+
meta: {
|
|
464
|
+
appId: '1234567890',
|
|
465
|
+
clientToken: 'abc123',
|
|
466
|
+
enableDeferredDeepLink: true,
|
|
467
|
+
enableAppEvents: true,
|
|
468
|
+
},
|
|
469
|
+
});
|
|
291
470
|
```
|
|
292
471
|
|
|
293
|
-
|
|
472
|
+
### TikTok
|
|
294
473
|
|
|
295
|
-
|
|
474
|
+
```typescript
|
|
475
|
+
await Datalyr.initialize({
|
|
476
|
+
apiKey: 'dk_your_api_key',
|
|
477
|
+
tiktok: {
|
|
478
|
+
appId: 'your_app_id',
|
|
479
|
+
tiktokAppId: '7123456789',
|
|
480
|
+
enableAppEvents: true,
|
|
481
|
+
},
|
|
482
|
+
});
|
|
483
|
+
```
|
|
484
|
+
|
|
485
|
+
### App Tracking Transparency
|
|
486
|
+
|
|
487
|
+
Update after ATT dialog:
|
|
296
488
|
|
|
297
489
|
```typescript
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
490
|
+
const { status } = await requestTrackingPermissionsAsync();
|
|
491
|
+
await Datalyr.updateTrackingAuthorization(status === 'granted');
|
|
492
|
+
```
|
|
301
493
|
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
494
|
+
### Check Status
|
|
495
|
+
|
|
496
|
+
```typescript
|
|
497
|
+
const status = Datalyr.getPlatformIntegrationStatus();
|
|
498
|
+
// { meta: true, tiktok: true }
|
|
305
499
|
```
|
|
306
500
|
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
### Methods
|
|
310
|
-
|
|
311
|
-
| Method | Description |
|
|
312
|
-
|--------|-------------|
|
|
313
|
-
| `initialize(config)` | Initialize SDK with configuration |
|
|
314
|
-
| `track(event, properties?)` | Track custom event |
|
|
315
|
-
| `identify(userId, properties?)` | Identify user |
|
|
316
|
-
| `screen(name, properties?)` | Track screen view |
|
|
317
|
-
| `alias(newUserId, previousId?)` | Create user alias |
|
|
318
|
-
| `reset()` | Reset user session |
|
|
319
|
-
| `flush()` | Flush event queue |
|
|
320
|
-
| `getStatus()` | Get SDK status |
|
|
321
|
-
| `getAttributionData()` | Get attribution data |
|
|
322
|
-
| `setAttributionData(data)` | Set attribution data |
|
|
323
|
-
| `getCurrentSession()` | Get current session |
|
|
324
|
-
| `endSession()` | End current session |
|
|
325
|
-
| `trackPurchase(value, currency, productId?)` | Track purchase |
|
|
326
|
-
| `trackSubscription(value, currency, plan?)` | Track subscription |
|
|
327
|
-
| `trackRevenue(event, properties?)` | Track revenue event |
|
|
501
|
+
---
|
|
328
502
|
|
|
329
|
-
##
|
|
503
|
+
## Expo Support
|
|
330
504
|
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
3. Verify network connectivity
|
|
335
|
-
4. Check `getStatus()` for queue information
|
|
505
|
+
```typescript
|
|
506
|
+
import { Datalyr } from '@datalyr/react-native/expo';
|
|
507
|
+
```
|
|
336
508
|
|
|
337
|
-
|
|
338
|
-
- Ensure API key starts with `dk_`
|
|
339
|
-
- Get your API key from: https://app.datalyr.com/settings/api-keys
|
|
509
|
+
Same API as standard React Native.
|
|
340
510
|
|
|
341
|
-
|
|
342
|
-
```bash
|
|
343
|
-
# Clear caches
|
|
344
|
-
npx react-native clean-project
|
|
511
|
+
---
|
|
345
512
|
|
|
346
|
-
|
|
347
|
-
|
|
513
|
+
## TypeScript
|
|
514
|
+
|
|
515
|
+
```typescript
|
|
516
|
+
import {
|
|
517
|
+
Datalyr,
|
|
518
|
+
DatalyrConfig,
|
|
519
|
+
EventData,
|
|
520
|
+
UserProperties,
|
|
521
|
+
AttributionData,
|
|
522
|
+
} from '@datalyr/react-native';
|
|
348
523
|
```
|
|
349
524
|
|
|
350
|
-
|
|
525
|
+
---
|
|
526
|
+
|
|
527
|
+
## Troubleshooting
|
|
351
528
|
|
|
352
|
-
|
|
353
|
-
- 📚 Docs: https://docs.datalyr.com
|
|
354
|
-
- 🐛 Issues: https://github.com/datalyr/react-native/issues
|
|
529
|
+
### Events not appearing
|
|
355
530
|
|
|
356
|
-
|
|
531
|
+
1. Check API key starts with `dk_`
|
|
532
|
+
2. Enable `debug: true`
|
|
533
|
+
3. Check `Datalyr.getStatus()` for queue info
|
|
534
|
+
4. Verify network connectivity
|
|
535
|
+
|
|
536
|
+
### iOS build errors
|
|
537
|
+
|
|
538
|
+
```bash
|
|
539
|
+
cd ios && pod deintegrate && pod install
|
|
540
|
+
```
|
|
541
|
+
|
|
542
|
+
### Meta/TikTok not working
|
|
357
543
|
|
|
358
|
-
|
|
544
|
+
Verify Info.plist contains required keys (see Installation).
|
|
359
545
|
|
|
360
546
|
---
|
|
361
547
|
|
|
362
|
-
|
|
548
|
+
## License
|
|
549
|
+
|
|
550
|
+
MIT
|