@datalyr/react-native 1.6.1 → 1.6.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/README.md +522 -60
- package/lib/datalyr-sdk.js +3 -4
- package/lib/http-client.js +1 -1
- package/lib/types.d.ts +2 -2
- package/package.json +1 -1
- package/src/datalyr-sdk-expo.ts +2 -2
- package/src/datalyr-sdk.ts +3 -4
- package/src/http-client.ts +2 -2
- package/src/types.ts +2 -2
package/README.md
CHANGED
|
@@ -12,13 +12,20 @@ Mobile analytics and attribution SDK for React Native and Expo. Track events, id
|
|
|
12
12
|
- [Custom Events](#custom-events)
|
|
13
13
|
- [Screen Views](#screen-views)
|
|
14
14
|
- [E-Commerce Events](#e-commerce-events)
|
|
15
|
+
- [Revenue Events](#revenue-events)
|
|
15
16
|
- [User Identity](#user-identity)
|
|
16
17
|
- [Anonymous ID](#anonymous-id)
|
|
17
18
|
- [Identifying Users](#identifying-users)
|
|
19
|
+
- [Alias](#alias)
|
|
18
20
|
- [User Properties](#user-properties)
|
|
21
|
+
- [Logout](#logout)
|
|
22
|
+
- [Sessions](#sessions)
|
|
19
23
|
- [Attribution](#attribution)
|
|
20
24
|
- [Automatic Capture](#automatic-capture)
|
|
25
|
+
- [Manual Attribution](#manual-attribution)
|
|
21
26
|
- [Web-to-App Attribution](#web-to-app-attribution)
|
|
27
|
+
- [Deferred Attribution](#deferred-attribution)
|
|
28
|
+
- [Customer Journey](#customer-journey)
|
|
22
29
|
- [Event Queue](#event-queue)
|
|
23
30
|
- [Auto Events](#auto-events)
|
|
24
31
|
- [SKAdNetwork](#skadnetwork)
|
|
@@ -27,12 +34,16 @@ Mobile analytics and attribution SDK for React Native and Expo. Track events, id
|
|
|
27
34
|
- [TikTok](#tiktok)
|
|
28
35
|
- [Google Ads](#google-ads)
|
|
29
36
|
- [Apple Search Ads](#apple-search-ads)
|
|
37
|
+
- [Google Play Install Referrer](#google-play-install-referrer)
|
|
38
|
+
- [App Tracking Transparency](#app-tracking-transparency)
|
|
39
|
+
- [Enhanced App Campaigns](#enhanced-app-campaigns)
|
|
30
40
|
- [Third-Party Integrations](#third-party-integrations)
|
|
31
41
|
- [Superwall](#superwall)
|
|
32
42
|
- [RevenueCat](#revenuecat)
|
|
33
43
|
- [Migrating from AppsFlyer / Adjust](#migrating-from-appsflyer--adjust)
|
|
34
44
|
- [Expo Support](#expo-support)
|
|
35
45
|
- [TypeScript](#typescript)
|
|
46
|
+
- [API Reference](#api-reference)
|
|
36
47
|
- [Troubleshooting](#troubleshooting)
|
|
37
48
|
- [License](#license)
|
|
38
49
|
|
|
@@ -125,24 +136,62 @@ Every event includes:
|
|
|
125
136
|
|
|
126
137
|
## Configuration
|
|
127
138
|
|
|
139
|
+
All fields except `apiKey` are optional.
|
|
140
|
+
|
|
128
141
|
```typescript
|
|
129
142
|
await Datalyr.initialize({
|
|
130
143
|
// Required
|
|
131
|
-
apiKey: string,
|
|
144
|
+
apiKey: string, // API key from dashboard (starts with 'dk_')
|
|
145
|
+
|
|
146
|
+
// Optional: workspace
|
|
147
|
+
workspaceId?: string, // Workspace ID for multi-workspace setups
|
|
148
|
+
|
|
149
|
+
// Debugging
|
|
150
|
+
debug?: boolean, // Console logging (default: false)
|
|
151
|
+
|
|
152
|
+
// Network
|
|
153
|
+
endpoint?: string, // API endpoint URL (default: 'https://api.datalyr.com')
|
|
154
|
+
useServerTracking?: boolean, // Use server-side tracking (default: true)
|
|
155
|
+
maxRetries?: number, // Max retry attempts for failed requests (default: 3)
|
|
156
|
+
retryDelay?: number, // Delay between retries in ms (default: 1000)
|
|
157
|
+
timeout?: number, // Request timeout in ms (default: 15000)
|
|
132
158
|
|
|
133
159
|
// Features
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
160
|
+
enableAutoEvents?: boolean, // Track app lifecycle automatically (default: true)
|
|
161
|
+
enableAttribution?: boolean, // Capture attribution data (default: true)
|
|
162
|
+
enableWebToAppAttribution?: boolean, // Web-to-app attribution matching (default: true)
|
|
137
163
|
|
|
138
|
-
// Event
|
|
139
|
-
batchSize?: number,
|
|
140
|
-
flushInterval?: number,
|
|
141
|
-
maxQueueSize?: number,
|
|
164
|
+
// Event queue
|
|
165
|
+
batchSize?: number, // Events per batch (default: 10)
|
|
166
|
+
flushInterval?: number, // Auto-flush interval in ms (default: 30000)
|
|
167
|
+
maxQueueSize?: number, // Max queued events (default: 100)
|
|
168
|
+
|
|
169
|
+
// Auto events
|
|
170
|
+
autoEventConfig?: AutoEventConfig, // Fine-grained auto-event settings (see below)
|
|
142
171
|
|
|
143
172
|
// iOS
|
|
144
|
-
skadTemplate?: 'ecommerce' | 'gaming' | 'subscription',
|
|
173
|
+
skadTemplate?: 'ecommerce' | 'gaming' | 'subscription', // SKAdNetwork conversion template
|
|
174
|
+
});
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
### AutoEventConfig
|
|
178
|
+
|
|
179
|
+
```typescript
|
|
180
|
+
interface AutoEventConfig {
|
|
181
|
+
trackSessions?: boolean; // Track session_start / session_end
|
|
182
|
+
trackScreenViews?: boolean; // Track screen views automatically
|
|
183
|
+
trackAppUpdates?: boolean; // Track app_update events
|
|
184
|
+
trackPerformance?: boolean; // Track performance metrics
|
|
185
|
+
sessionTimeoutMs?: number; // Session timeout in ms
|
|
186
|
+
}
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
Update at runtime:
|
|
145
190
|
|
|
191
|
+
```typescript
|
|
192
|
+
Datalyr.updateAutoEventsConfig({
|
|
193
|
+
trackSessions: true,
|
|
194
|
+
sessionTimeoutMs: 1800000, // 30 minutes
|
|
146
195
|
});
|
|
147
196
|
```
|
|
148
197
|
|
|
@@ -152,8 +201,6 @@ await Datalyr.initialize({
|
|
|
152
201
|
|
|
153
202
|
### Custom Events
|
|
154
203
|
|
|
155
|
-
Track any action in your app:
|
|
156
|
-
|
|
157
204
|
```typescript
|
|
158
205
|
// Simple event
|
|
159
206
|
await Datalyr.track('signup_started');
|
|
@@ -177,8 +224,6 @@ await Datalyr.track('level_completed', {
|
|
|
177
224
|
|
|
178
225
|
### Screen Views
|
|
179
226
|
|
|
180
|
-
Track navigation:
|
|
181
|
-
|
|
182
227
|
```typescript
|
|
183
228
|
await Datalyr.screen('Home');
|
|
184
229
|
|
|
@@ -221,6 +266,26 @@ await Datalyr.trackLead(100.0, 'USD');
|
|
|
221
266
|
await Datalyr.trackAddPaymentInfo(true);
|
|
222
267
|
```
|
|
223
268
|
|
|
269
|
+
### Revenue Events
|
|
270
|
+
|
|
271
|
+
Track revenue with automatic SKAdNetwork encoding:
|
|
272
|
+
|
|
273
|
+
```typescript
|
|
274
|
+
await Datalyr.trackRevenue('in_app_purchase', {
|
|
275
|
+
value: 4.99,
|
|
276
|
+
currency: 'USD',
|
|
277
|
+
product_id: 'gems_500',
|
|
278
|
+
});
|
|
279
|
+
```
|
|
280
|
+
|
|
281
|
+
### App Update Tracking
|
|
282
|
+
|
|
283
|
+
Manually track version changes:
|
|
284
|
+
|
|
285
|
+
```typescript
|
|
286
|
+
await Datalyr.trackAppUpdate('1.0.0', '1.1.0');
|
|
287
|
+
```
|
|
288
|
+
|
|
224
289
|
---
|
|
225
290
|
|
|
226
291
|
## User Identity
|
|
@@ -253,6 +318,18 @@ After `identify()`:
|
|
|
253
318
|
- All future events include `user_id`
|
|
254
319
|
- Historical anonymous events can be linked server-side
|
|
255
320
|
|
|
321
|
+
### Alias
|
|
322
|
+
|
|
323
|
+
Associate a new user ID with a previous one. Use this when a user's identity changes (e.g., after account merge):
|
|
324
|
+
|
|
325
|
+
```typescript
|
|
326
|
+
// Link new ID to the currently identified user
|
|
327
|
+
await Datalyr.alias('new_user_456');
|
|
328
|
+
|
|
329
|
+
// Or specify the previous ID explicitly
|
|
330
|
+
await Datalyr.alias('new_user_456', 'old_user_123');
|
|
331
|
+
```
|
|
332
|
+
|
|
256
333
|
### User Properties
|
|
257
334
|
|
|
258
335
|
Pass any user attributes:
|
|
@@ -286,6 +363,20 @@ This:
|
|
|
286
363
|
|
|
287
364
|
---
|
|
288
365
|
|
|
366
|
+
## Sessions
|
|
367
|
+
|
|
368
|
+
```typescript
|
|
369
|
+
// Get current session data
|
|
370
|
+
const session = Datalyr.getCurrentSession();
|
|
371
|
+
|
|
372
|
+
// Force end the current session
|
|
373
|
+
await Datalyr.endSession();
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
Sessions are managed automatically when `enableAutoEvents` is enabled. A new session starts on app launch, and the current session ends after 30 minutes of inactivity (configurable via `autoEventConfig.sessionTimeoutMs`).
|
|
377
|
+
|
|
378
|
+
---
|
|
379
|
+
|
|
289
380
|
## Attribution
|
|
290
381
|
|
|
291
382
|
### Automatic Capture
|
|
@@ -304,13 +395,24 @@ Captured parameters:
|
|
|
304
395
|
| Click IDs | `fbclid`, `gclid`, `ttclid`, `twclid`, `li_click_id`, `msclkid` |
|
|
305
396
|
| Campaign | `campaign_id`, `adset_id`, `ad_id` |
|
|
306
397
|
|
|
398
|
+
### Manual Attribution
|
|
399
|
+
|
|
400
|
+
Set attribution programmatically:
|
|
401
|
+
|
|
402
|
+
```typescript
|
|
403
|
+
await Datalyr.setAttributionData({
|
|
404
|
+
utm_source: 'newsletter',
|
|
405
|
+
utm_campaign: 'spring_sale',
|
|
406
|
+
});
|
|
407
|
+
```
|
|
408
|
+
|
|
307
409
|
### Web-to-App Attribution
|
|
308
410
|
|
|
309
411
|
Automatically recover attribution from a web prelander when users install the app from an ad.
|
|
310
412
|
|
|
311
413
|
**How it works:**
|
|
312
|
-
- **Android**: Attribution params are passed through the Play Store `referrer` URL parameter (set by the web SDK's `trackAppDownloadClick()`). The mobile SDK reads these via the Play Install Referrer API
|
|
313
|
-
- **iOS**: On first install, the SDK calls the Datalyr API to match the device's IP against recent `$app_download_click` web events within 24 hours
|
|
414
|
+
- **Android**: Attribution params are passed through the Play Store `referrer` URL parameter (set by the web SDK's `trackAppDownloadClick()`). The mobile SDK reads these via the Play Install Referrer API -- deterministic, ~95% accuracy.
|
|
415
|
+
- **iOS**: On first install, the SDK calls the Datalyr API to match the device's IP against recent `$app_download_click` web events within 24 hours -- ~90%+ accuracy for immediate installs.
|
|
314
416
|
|
|
315
417
|
No additional mobile code is needed. Attribution is recovered automatically during `initialize()` on first install, before the `app_install` event fires.
|
|
316
418
|
|
|
@@ -321,15 +423,43 @@ After a match, the SDK:
|
|
|
321
423
|
|
|
322
424
|
**Fallback:** If IP matching misses (e.g., VPN toggle during install), email-based attribution is still recovered when `identify()` is called with the user's email.
|
|
323
425
|
|
|
324
|
-
###
|
|
426
|
+
### Deferred Attribution
|
|
325
427
|
|
|
326
|
-
|
|
428
|
+
Retrieve deferred attribution data captured from deep links or install referrers:
|
|
327
429
|
|
|
328
430
|
```typescript
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
431
|
+
const deferred = Datalyr.getDeferredAttributionData();
|
|
432
|
+
if (deferred) {
|
|
433
|
+
console.log(deferred.url); // Deep link URL
|
|
434
|
+
console.log(deferred.source); // Attribution source
|
|
435
|
+
console.log(deferred.fbclid); // Facebook click ID
|
|
436
|
+
console.log(deferred.gclid); // Google click ID
|
|
437
|
+
console.log(deferred.ttclid); // TikTok click ID
|
|
438
|
+
console.log(deferred.utmSource); // UTM source
|
|
439
|
+
console.log(deferred.utmMedium); // UTM medium
|
|
440
|
+
console.log(deferred.utmCampaign); // UTM campaign
|
|
441
|
+
console.log(deferred.utmContent); // UTM content
|
|
442
|
+
console.log(deferred.utmTerm); // UTM term
|
|
443
|
+
console.log(deferred.campaignId); // Campaign ID
|
|
444
|
+
console.log(deferred.adsetId); // Adset ID
|
|
445
|
+
console.log(deferred.adId); // Ad ID
|
|
446
|
+
}
|
|
447
|
+
```
|
|
448
|
+
|
|
449
|
+
---
|
|
450
|
+
|
|
451
|
+
## Customer Journey
|
|
452
|
+
|
|
453
|
+
Access multi-touch attribution journey data via the `datalyr` singleton instance:
|
|
454
|
+
|
|
455
|
+
```typescript
|
|
456
|
+
import { datalyr } from '@datalyr/react-native';
|
|
457
|
+
|
|
458
|
+
// Summary: first/last touch, touchpoint count
|
|
459
|
+
const summary = datalyr.getJourneySummary();
|
|
460
|
+
|
|
461
|
+
// Full journey: all touchpoints in order
|
|
462
|
+
const journey = datalyr.getJourney();
|
|
333
463
|
```
|
|
334
464
|
|
|
335
465
|
---
|
|
@@ -407,7 +537,10 @@ await Datalyr.initialize({
|
|
|
407
537
|
skadTemplate: 'ecommerce',
|
|
408
538
|
});
|
|
409
539
|
|
|
410
|
-
//
|
|
540
|
+
// Track with automatic SKAN conversion value encoding
|
|
541
|
+
await Datalyr.trackWithSKAdNetwork('purchase', { value: 99.99 });
|
|
542
|
+
|
|
543
|
+
// Or use e-commerce helpers (also update SKAN automatically)
|
|
411
544
|
await Datalyr.trackPurchase(99.99, 'USD');
|
|
412
545
|
```
|
|
413
546
|
|
|
@@ -417,6 +550,15 @@ await Datalyr.trackPurchase(99.99, 'USD');
|
|
|
417
550
|
| `gaming` | level_complete, tutorial_complete, purchase, achievement_unlocked |
|
|
418
551
|
| `subscription` | trial_start, subscribe, upgrade, cancel, signup |
|
|
419
552
|
|
|
553
|
+
### Test Conversion Values
|
|
554
|
+
|
|
555
|
+
Preview the conversion value an event would produce without sending it to Apple:
|
|
556
|
+
|
|
557
|
+
```typescript
|
|
558
|
+
const value = Datalyr.getConversionValue('purchase', { value: 49.99 });
|
|
559
|
+
// Returns a number (0-63) or null if no template is configured
|
|
560
|
+
```
|
|
561
|
+
|
|
420
562
|
---
|
|
421
563
|
|
|
422
564
|
## Platform Integrations
|
|
@@ -434,7 +576,7 @@ Conversions are sent to Meta via the [Conversions API (CAPI)](https://developers
|
|
|
434
576
|
**Setup:**
|
|
435
577
|
1. Connect your Meta ad account in the Datalyr dashboard (Settings > Connections)
|
|
436
578
|
2. Select your Meta Pixel
|
|
437
|
-
3. Create postback rules to map events (e.g., `purchase`
|
|
579
|
+
3. Create postback rules to map events (e.g., `purchase` -> `Purchase`, `lead` -> `Lead`)
|
|
438
580
|
|
|
439
581
|
No Facebook SDK needed in your app. No `Info.plist` changes, no `FacebookAppID`.
|
|
440
582
|
|
|
@@ -449,7 +591,7 @@ Conversions are sent to TikTok via the [Events API](https://business-api.tiktok.
|
|
|
449
591
|
**Setup:**
|
|
450
592
|
1. Connect your TikTok Ads account in the Datalyr dashboard (Settings > Connections)
|
|
451
593
|
2. Select your TikTok Pixel
|
|
452
|
-
3. Create postback rules to map events (e.g., `purchase`
|
|
594
|
+
3. Create postback rules to map events (e.g., `purchase` -> `CompletePayment`, `add_to_cart` -> `AddToCart`)
|
|
453
595
|
|
|
454
596
|
No TikTok SDK needed in your app. No access tokens, no native configuration.
|
|
455
597
|
|
|
@@ -464,7 +606,7 @@ Conversions are sent to Google via the [Google Ads API](https://developers.googl
|
|
|
464
606
|
**Setup:**
|
|
465
607
|
1. Connect your Google Ads account in the Datalyr dashboard (Settings > Connections)
|
|
466
608
|
2. Select your conversion actions
|
|
467
|
-
3. Create postback rules to map events (e.g., `purchase`
|
|
609
|
+
3. Create postback rules to map events (e.g., `purchase` -> your Google conversion action)
|
|
468
610
|
|
|
469
611
|
No Google SDK needed in your app beyond the Play Install Referrer (already included for Android).
|
|
470
612
|
|
|
@@ -494,6 +636,52 @@ Attribution data is automatically included in all events with the `asa_` prefix:
|
|
|
494
636
|
|
|
495
637
|
No additional configuration needed. The SDK uses Apple's AdServices API.
|
|
496
638
|
|
|
639
|
+
### Google Play Install Referrer
|
|
640
|
+
|
|
641
|
+
Android-only. Captures UTM parameters and click IDs from the Google Play Store install referrer URL. This data is retrieved automatically on first launch via the Play Install Referrer API.
|
|
642
|
+
|
|
643
|
+
**How it works:**
|
|
644
|
+
1. User clicks an ad or link with UTM parameters
|
|
645
|
+
2. Google Play Store stores the referrer URL
|
|
646
|
+
3. On first app launch, the SDK retrieves the referrer
|
|
647
|
+
4. Attribution data (utm_source, utm_medium, gclid, etc.) is extracted and merged into the session
|
|
648
|
+
|
|
649
|
+
**Access the raw referrer data:**
|
|
650
|
+
|
|
651
|
+
```typescript
|
|
652
|
+
import { datalyr } from '@datalyr/react-native';
|
|
653
|
+
|
|
654
|
+
const referrer = datalyr.getPlayInstallReferrer();
|
|
655
|
+
if (referrer) {
|
|
656
|
+
// Google Ads click IDs
|
|
657
|
+
console.log(referrer.gclid); // Standard Google Ads click ID
|
|
658
|
+
console.log(referrer.gbraid); // Privacy-safe click ID (iOS App campaigns)
|
|
659
|
+
console.log(referrer.wbraid); // Privacy-safe click ID (Web-to-App campaigns)
|
|
660
|
+
|
|
661
|
+
// UTM parameters
|
|
662
|
+
console.log(referrer.utmSource);
|
|
663
|
+
console.log(referrer.utmMedium);
|
|
664
|
+
console.log(referrer.utmCampaign);
|
|
665
|
+
console.log(referrer.utmTerm);
|
|
666
|
+
console.log(referrer.utmContent);
|
|
667
|
+
|
|
668
|
+
// Timestamps
|
|
669
|
+
console.log(referrer.referrerClickTimestamp); // When the referrer link was clicked (ms)
|
|
670
|
+
console.log(referrer.installBeginTimestamp); // When the install began (ms)
|
|
671
|
+
console.log(referrer.installCompleteTimestamp); // When the install completed (ms)
|
|
672
|
+
|
|
673
|
+
// Raw referrer URL
|
|
674
|
+
console.log(referrer.referrerUrl);
|
|
675
|
+
}
|
|
676
|
+
```
|
|
677
|
+
|
|
678
|
+
**Requirements:**
|
|
679
|
+
- Android only (returns `null` on iOS)
|
|
680
|
+
- Requires the Google Play Install Referrer Library in `android/app/build.gradle`:
|
|
681
|
+
```groovy
|
|
682
|
+
implementation 'com.android.installreferrer:installreferrer:2.2'
|
|
683
|
+
```
|
|
684
|
+
|
|
497
685
|
### App Tracking Transparency
|
|
498
686
|
|
|
499
687
|
Update after ATT dialog:
|
|
@@ -503,37 +691,219 @@ const { status } = await requestTrackingPermissionsAsync();
|
|
|
503
691
|
await Datalyr.updateTrackingAuthorization(status === 'granted');
|
|
504
692
|
```
|
|
505
693
|
|
|
506
|
-
###
|
|
694
|
+
### Integration Status
|
|
507
695
|
|
|
508
696
|
```typescript
|
|
509
697
|
const status = Datalyr.getPlatformIntegrationStatus();
|
|
510
|
-
// { appleSearchAds:
|
|
698
|
+
// { appleSearchAds: boolean, playInstallReferrer: boolean }
|
|
511
699
|
```
|
|
512
700
|
|
|
513
701
|
---
|
|
514
702
|
|
|
515
|
-
##
|
|
703
|
+
## Enhanced App Campaigns
|
|
704
|
+
|
|
705
|
+
Run mobile app ads through web campaigns (Meta Sales, TikTok Traffic, Google Ads) that redirect users to the app store through your own domain. This bypasses SKAN restrictions, ATT requirements, and adset limits -- ad platforms treat these as regular web campaigns.
|
|
706
|
+
|
|
707
|
+
### How It Works
|
|
708
|
+
|
|
709
|
+
1. User clicks your ad -> lands on a page on your domain with the Datalyr web SDK (`dl.js`)
|
|
710
|
+
2. SDK captures attribution (fbclid, ttclid, gclid, UTMs, ad cookies like `_fbp`/`_fbc`/`_ttp`)
|
|
711
|
+
3. User redirects to app store (via button click or auto-redirect)
|
|
712
|
+
4. User installs app -> mobile SDK matches via Play Store referrer (Android, ~95%) or IP matching (iOS, ~90%+)
|
|
713
|
+
5. In-app events fire -> conversions sent to Meta/TikTok/Google server-side via postbacks
|
|
714
|
+
|
|
715
|
+
### Setup
|
|
716
|
+
|
|
717
|
+
**1. Create a tracking link** in the Datalyr dashboard: Track -> Create Link -> App Link. Enter your prelander page URL and app store URLs.
|
|
718
|
+
|
|
719
|
+
**2. Host a page on your domain** with one of these options:
|
|
720
|
+
|
|
721
|
+
#### Option A: Prelander (Recommended)
|
|
722
|
+
|
|
723
|
+
A real landing page with a download button. Better ad platform compliance, higher intent.
|
|
724
|
+
|
|
725
|
+
```html
|
|
726
|
+
<!DOCTYPE html>
|
|
727
|
+
<html>
|
|
728
|
+
<head>
|
|
729
|
+
<meta charset="utf-8">
|
|
730
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
731
|
+
<title>Download Your App</title>
|
|
732
|
+
<script src="https://cdn.datalyr.com/dl.js" data-workspace="YOUR_WORKSPACE_ID"></script>
|
|
733
|
+
</head>
|
|
734
|
+
<body>
|
|
735
|
+
<h1>Download Our App</h1>
|
|
736
|
+
<button id="ios-download">Download for iOS</button>
|
|
737
|
+
<button id="android-download">Download for Android</button>
|
|
738
|
+
|
|
739
|
+
<script>
|
|
740
|
+
document.getElementById('ios-download').addEventListener('click', function() {
|
|
741
|
+
Datalyr.trackAppDownloadClick({
|
|
742
|
+
targetPlatform: 'ios',
|
|
743
|
+
appStoreUrl: 'https://apps.apple.com/app/idXXXXXXXXXX'
|
|
744
|
+
});
|
|
745
|
+
});
|
|
746
|
+
document.getElementById('android-download').addEventListener('click', function() {
|
|
747
|
+
Datalyr.trackAppDownloadClick({
|
|
748
|
+
targetPlatform: 'android',
|
|
749
|
+
appStoreUrl: 'https://play.google.com/store/apps/details?id=com.example.app'
|
|
750
|
+
});
|
|
751
|
+
});
|
|
752
|
+
</script>
|
|
753
|
+
</body>
|
|
754
|
+
</html>
|
|
755
|
+
```
|
|
516
756
|
|
|
517
|
-
|
|
518
|
-
|
|
757
|
+
#### Option B: Redirect Page
|
|
758
|
+
|
|
759
|
+
Instant redirect -- no visible content, user goes straight to app store.
|
|
760
|
+
|
|
761
|
+
> **Note:** Some ad platforms (particularly Meta) may flag redirect pages with no visible content as low-quality landing pages or cloaking. Use the prelander option if compliance is a concern.
|
|
762
|
+
|
|
763
|
+
```html
|
|
764
|
+
<!DOCTYPE html>
|
|
765
|
+
<html>
|
|
766
|
+
<head>
|
|
767
|
+
<script src="https://cdn.datalyr.com/dl.js" data-workspace="YOUR_WORKSPACE_ID"></script>
|
|
768
|
+
<script>
|
|
769
|
+
window.addEventListener('DOMContentLoaded', function() {
|
|
770
|
+
var isAndroid = /android/i.test(navigator.userAgent);
|
|
771
|
+
Datalyr.trackAppDownloadClick({
|
|
772
|
+
targetPlatform: isAndroid ? 'android' : 'ios',
|
|
773
|
+
appStoreUrl: isAndroid
|
|
774
|
+
? 'https://play.google.com/store/apps/details?id=com.example.app'
|
|
775
|
+
: 'https://apps.apple.com/app/idXXXXXXXXXX'
|
|
776
|
+
});
|
|
777
|
+
});
|
|
778
|
+
</script>
|
|
779
|
+
</head>
|
|
780
|
+
<body></body>
|
|
781
|
+
</html>
|
|
519
782
|
```
|
|
520
783
|
|
|
521
|
-
|
|
784
|
+
**3. Set up your ad campaign:**
|
|
785
|
+
|
|
786
|
+
- **Meta Ads**: Campaign objective -> Sales, conversion location -> Website, placements -> Mobile only. Paste your page URL as the Website URL. No SKAN, no ATT, no adset limits.
|
|
787
|
+
- **TikTok Ads**: Campaign objective -> Website Conversions, paste your page URL as destination. Select your TikTok Pixel from Datalyr.
|
|
788
|
+
- **Google Ads**: Performance Max or Search campaign. Use your page URL as the landing page.
|
|
789
|
+
|
|
790
|
+
Add UTM parameters to the URL so attribution flows through:
|
|
791
|
+
- Meta: `?utm_source=facebook&utm_medium=cpc&utm_campaign={{campaign.name}}&utm_content={{adset.name}}&utm_term={{ad.name}}`
|
|
792
|
+
- TikTok: `?utm_source=tiktok&utm_medium=cpc&utm_campaign=__CAMPAIGN_NAME__&utm_content=__AID_NAME__&utm_term=__CID_NAME__`
|
|
793
|
+
- Google: `?utm_source=google&utm_medium=cpc&utm_campaign={campaignid}&utm_content={adgroupid}&utm_term={keyword}`
|
|
794
|
+
|
|
795
|
+
### Important
|
|
796
|
+
|
|
797
|
+
- The page **must load JavaScript**. Server-side redirects (301/302, nginx, Cloudflare Page Rules) will NOT work.
|
|
798
|
+
- Host on your own domain -- do not use `datalyr.com` or shared domains.
|
|
799
|
+
- The redirect page adds ~100-200ms for the SDK to load. Prelander has no latency since the user clicks a button.
|
|
522
800
|
|
|
523
801
|
---
|
|
524
802
|
|
|
525
|
-
##
|
|
803
|
+
## Third-Party Integrations
|
|
804
|
+
|
|
805
|
+
### Superwall
|
|
806
|
+
|
|
807
|
+
Pass Datalyr attribution data to Superwall to personalize paywalls by ad source, campaign, ad set, and keyword.
|
|
526
808
|
|
|
527
809
|
```typescript
|
|
528
|
-
import {
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
810
|
+
import { Datalyr } from '@datalyr/react-native';
|
|
811
|
+
import Superwall from '@superwall/react-native-superwall';
|
|
812
|
+
|
|
813
|
+
// After both SDKs are initialized
|
|
814
|
+
Superwall.setUserAttributes(Datalyr.getSuperwallAttributes());
|
|
815
|
+
|
|
816
|
+
// Your placements will now have attribution data available as filters
|
|
817
|
+
Superwall.register({ placement: 'onboarding_paywall' });
|
|
818
|
+
```
|
|
819
|
+
|
|
820
|
+
Call after `Datalyr.initialize()` completes. If using ATT on iOS, call again after the user responds to the ATT prompt to include the IDFA.
|
|
821
|
+
|
|
822
|
+
**Returned attribute keys:**
|
|
823
|
+
|
|
824
|
+
| Key | Description |
|
|
825
|
+
|-----|-------------|
|
|
826
|
+
| `datalyr_id` | The user's DATALYR visitor ID |
|
|
827
|
+
| `media_source` | Traffic source (e.g., `facebook`, `google`) |
|
|
828
|
+
| `campaign` | Campaign name from the ad |
|
|
829
|
+
| `adgroup` | Ad group or ad set name |
|
|
830
|
+
| `ad` | Individual ad ID |
|
|
831
|
+
| `keyword` | Search keyword that triggered the ad |
|
|
832
|
+
| `network` | Ad network name |
|
|
833
|
+
| `utm_source` | UTM source parameter |
|
|
834
|
+
| `utm_medium` | UTM medium parameter (e.g., `cpc`) |
|
|
835
|
+
| `utm_campaign` | UTM campaign parameter |
|
|
836
|
+
| `utm_term` | UTM term parameter |
|
|
837
|
+
| `utm_content` | UTM content parameter |
|
|
838
|
+
| `lyr` | DATALYR tracking link ID |
|
|
839
|
+
| `fbclid` | Meta click ID from the ad URL |
|
|
840
|
+
| `gclid` | Google click ID from the ad URL |
|
|
841
|
+
| `ttclid` | TikTok click ID from the ad URL |
|
|
842
|
+
| `idfa` | Apple advertising ID (only if ATT authorized) |
|
|
843
|
+
| `gaid` | Google advertising ID (Android) |
|
|
844
|
+
| `att_status` | App Tracking Transparency status (`0`-`3`) |
|
|
845
|
+
|
|
846
|
+
Only non-empty values are included.
|
|
847
|
+
|
|
848
|
+
### RevenueCat
|
|
849
|
+
|
|
850
|
+
Pass Datalyr attribution data to RevenueCat for revenue attribution and offering targeting.
|
|
851
|
+
|
|
852
|
+
```typescript
|
|
853
|
+
import { Datalyr } from '@datalyr/react-native';
|
|
854
|
+
import Purchases from 'react-native-purchases';
|
|
855
|
+
|
|
856
|
+
// After both SDKs are configured
|
|
857
|
+
Purchases.setAttributes(Datalyr.getRevenueCatAttributes());
|
|
535
858
|
```
|
|
536
859
|
|
|
860
|
+
Call after configuring the Purchases SDK and before the first purchase. If using ATT, call again after permission is granted to include IDFA.
|
|
861
|
+
|
|
862
|
+
**Reserved attributes (`$`-prefixed):**
|
|
863
|
+
|
|
864
|
+
| Key | Description |
|
|
865
|
+
|-----|-------------|
|
|
866
|
+
| `$datalyrId` | The user's DATALYR visitor ID |
|
|
867
|
+
| `$mediaSource` | Traffic source (e.g., `facebook`, `google`) |
|
|
868
|
+
| `$campaign` | Campaign name from the ad |
|
|
869
|
+
| `$adGroup` | Ad group or ad set name |
|
|
870
|
+
| `$ad` | Individual ad ID |
|
|
871
|
+
| `$keyword` | Search keyword that triggered the ad |
|
|
872
|
+
| `$idfa` | Apple advertising ID (only if ATT authorized) |
|
|
873
|
+
| `$gpsAdId` | Google advertising ID (Android) |
|
|
874
|
+
| `$attConsentStatus` | ATT consent status (see mapping below) |
|
|
875
|
+
|
|
876
|
+
**ATT status mapping for `$attConsentStatus`:**
|
|
877
|
+
|
|
878
|
+
| ATT Value | String |
|
|
879
|
+
|-----------|--------|
|
|
880
|
+
| 0 | `notDetermined` |
|
|
881
|
+
| 1 | `restricted` |
|
|
882
|
+
| 2 | `denied` |
|
|
883
|
+
| 3 | `authorized` |
|
|
884
|
+
|
|
885
|
+
**Custom attributes:**
|
|
886
|
+
|
|
887
|
+
| Key | Description |
|
|
888
|
+
|-----|-------------|
|
|
889
|
+
| `utm_source` | UTM source parameter |
|
|
890
|
+
| `utm_medium` | UTM medium parameter (e.g., `cpc`) |
|
|
891
|
+
| `utm_campaign` | UTM campaign parameter |
|
|
892
|
+
| `utm_term` | UTM term parameter |
|
|
893
|
+
| `utm_content` | UTM content parameter |
|
|
894
|
+
| `lyr` | DATALYR tracking link ID |
|
|
895
|
+
| `fbclid` | Meta click ID from the ad URL |
|
|
896
|
+
| `gclid` | Google click ID from the ad URL |
|
|
897
|
+
| `ttclid` | TikTok click ID from the ad URL |
|
|
898
|
+
| `wbraid` | Google web-to-app click ID |
|
|
899
|
+
| `gbraid` | Google app click ID |
|
|
900
|
+
| `network` | Ad network |
|
|
901
|
+
| `creative_id` | Creative ID |
|
|
902
|
+
|
|
903
|
+
Only non-empty values are included.
|
|
904
|
+
|
|
905
|
+
> Datalyr also receives Superwall and RevenueCat events via server-side webhooks for analytics. The SDK methods and webhook integration are independent -- you can use one or both.
|
|
906
|
+
|
|
537
907
|
---
|
|
538
908
|
|
|
539
909
|
## Migrating from AppsFlyer / Adjust
|
|
@@ -587,40 +957,132 @@ await Datalyr.trackPurchase(99.99, 'USD');
|
|
|
587
957
|
|
|
588
958
|
---
|
|
589
959
|
|
|
590
|
-
##
|
|
960
|
+
## Expo Support
|
|
591
961
|
|
|
592
|
-
|
|
962
|
+
```typescript
|
|
963
|
+
import { Datalyr } from '@datalyr/react-native/expo';
|
|
964
|
+
```
|
|
593
965
|
|
|
594
|
-
|
|
966
|
+
Same API as standard React Native.
|
|
595
967
|
|
|
596
|
-
|
|
597
|
-
import Datalyr from '@datalyr/react-native';
|
|
598
|
-
import Superwall from '@superwall/react-native-superwall';
|
|
968
|
+
---
|
|
599
969
|
|
|
600
|
-
|
|
601
|
-
Superwall.setUserAttributes(Datalyr.getSuperwallAttributes());
|
|
970
|
+
## TypeScript
|
|
602
971
|
|
|
603
|
-
|
|
604
|
-
|
|
972
|
+
```typescript
|
|
973
|
+
import {
|
|
974
|
+
Datalyr,
|
|
975
|
+
DatalyrConfig,
|
|
976
|
+
EventData,
|
|
977
|
+
UserProperties,
|
|
978
|
+
AttributionData,
|
|
979
|
+
AutoEventConfig,
|
|
980
|
+
DeferredDeepLinkResult,
|
|
981
|
+
} from '@datalyr/react-native';
|
|
605
982
|
```
|
|
606
983
|
|
|
607
|
-
|
|
984
|
+
---
|
|
608
985
|
|
|
609
|
-
|
|
986
|
+
## API Reference
|
|
610
987
|
|
|
611
|
-
|
|
988
|
+
All methods are static on the `Datalyr` class unless noted otherwise.
|
|
612
989
|
|
|
613
|
-
|
|
614
|
-
import Datalyr from '@datalyr/react-native';
|
|
615
|
-
import Purchases from 'react-native-purchases';
|
|
990
|
+
### Initialization
|
|
616
991
|
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
992
|
+
| Method | Description |
|
|
993
|
+
|--------|-------------|
|
|
994
|
+
| `initialize(config: DatalyrConfig)` | Initialize the SDK. Must be called before any other method. |
|
|
620
995
|
|
|
621
|
-
|
|
996
|
+
### Event Tracking
|
|
997
|
+
|
|
998
|
+
| Method | Description |
|
|
999
|
+
|--------|-------------|
|
|
1000
|
+
| `track(eventName, eventData?)` | Track a custom event |
|
|
1001
|
+
| `screen(screenName, properties?)` | Track a screen view |
|
|
1002
|
+
| `trackWithSKAdNetwork(event, properties?)` | Track event with SKAN conversion value encoding |
|
|
1003
|
+
| `trackPurchase(value, currency?, productId?)` | Track a purchase |
|
|
1004
|
+
| `trackSubscription(value, currency?, plan?)` | Track a subscription |
|
|
1005
|
+
| `trackRevenue(eventName, properties?)` | Track a revenue event |
|
|
1006
|
+
| `trackAddToCart(value, currency?, productId?, productName?)` | Track add-to-cart |
|
|
1007
|
+
| `trackViewContent(contentId?, contentName?, contentType?, value?, currency?)` | Track content view |
|
|
1008
|
+
| `trackInitiateCheckout(value, currency?, numItems?, productIds?)` | Track checkout start |
|
|
1009
|
+
| `trackCompleteRegistration(method?)` | Track registration |
|
|
1010
|
+
| `trackSearch(query, resultIds?)` | Track a search |
|
|
1011
|
+
| `trackLead(value?, currency?)` | Track a lead |
|
|
1012
|
+
| `trackAddPaymentInfo(success?)` | Track payment info added |
|
|
1013
|
+
| `trackAppUpdate(previousVersion, currentVersion)` | Track an app version update |
|
|
1014
|
+
|
|
1015
|
+
### User Identity
|
|
1016
|
+
|
|
1017
|
+
| Method | Description |
|
|
1018
|
+
|--------|-------------|
|
|
1019
|
+
| `identify(userId, properties?)` | Identify a user |
|
|
1020
|
+
| `alias(newUserId, previousId?)` | Associate a new user ID with a previous one |
|
|
1021
|
+
| `reset()` | Clear user ID and start new session |
|
|
1022
|
+
| `getAnonymousId()` | Get the persistent anonymous device ID |
|
|
1023
|
+
|
|
1024
|
+
### Sessions
|
|
1025
|
+
|
|
1026
|
+
| Method | Description |
|
|
1027
|
+
|--------|-------------|
|
|
1028
|
+
| `getCurrentSession()` | Get current session data |
|
|
1029
|
+
| `endSession()` | Force end the current session |
|
|
1030
|
+
|
|
1031
|
+
### Attribution
|
|
1032
|
+
|
|
1033
|
+
| Method | Description |
|
|
1034
|
+
|--------|-------------|
|
|
1035
|
+
| `getAttributionData()` | Get captured attribution data |
|
|
1036
|
+
| `setAttributionData(data)` | Set attribution data manually |
|
|
1037
|
+
| `getDeferredAttributionData()` | Get deferred attribution from deep links / install referrer |
|
|
1038
|
+
|
|
1039
|
+
### Configuration
|
|
1040
|
+
|
|
1041
|
+
| Method | Description |
|
|
1042
|
+
|--------|-------------|
|
|
1043
|
+
| `updateAutoEventsConfig(config)` | Update auto-event settings at runtime |
|
|
1044
|
+
|
|
1045
|
+
### Platform Integrations
|
|
1046
|
+
|
|
1047
|
+
| Method | Description |
|
|
1048
|
+
|--------|-------------|
|
|
1049
|
+
| `getAppleSearchAdsAttribution()` | Get Apple Search Ads attribution (iOS) |
|
|
1050
|
+
| `getPlatformIntegrationStatus()` | Check which platform integrations are active |
|
|
1051
|
+
| `updateTrackingAuthorization(enabled)` | Update ATT status after user responds to dialog |
|
|
1052
|
+
|
|
1053
|
+
### SKAdNetwork
|
|
1054
|
+
|
|
1055
|
+
| Method | Description |
|
|
1056
|
+
|--------|-------------|
|
|
1057
|
+
| `getConversionValue(event, properties?)` | Preview conversion value without sending to Apple |
|
|
1058
|
+
|
|
1059
|
+
### Third-Party Integrations
|
|
1060
|
+
|
|
1061
|
+
| Method | Description |
|
|
1062
|
+
|--------|-------------|
|
|
1063
|
+
| `getSuperwallAttributes()` | Get attribution formatted for Superwall |
|
|
1064
|
+
| `getRevenueCatAttributes()` | Get attribution formatted for RevenueCat |
|
|
1065
|
+
|
|
1066
|
+
### Status
|
|
1067
|
+
|
|
1068
|
+
| Method | Description |
|
|
1069
|
+
|--------|-------------|
|
|
1070
|
+
| `getStatus()` | Get SDK status (initialized, queue stats, online) |
|
|
1071
|
+
| `flush()` | Send all queued events immediately |
|
|
1072
|
+
|
|
1073
|
+
### Instance Methods (via `datalyr` singleton)
|
|
1074
|
+
|
|
1075
|
+
These methods are available on the `datalyr` instance export, not on the static `Datalyr` class:
|
|
1076
|
+
|
|
1077
|
+
```typescript
|
|
1078
|
+
import { datalyr } from '@datalyr/react-native';
|
|
1079
|
+
```
|
|
622
1080
|
|
|
623
|
-
|
|
1081
|
+
| Method | Description |
|
|
1082
|
+
|--------|-------------|
|
|
1083
|
+
| `getJourneySummary()` | Get journey summary (first/last touch, touchpoint count) |
|
|
1084
|
+
| `getJourney()` | Get full customer journey (all touchpoints) |
|
|
1085
|
+
| `getPlayInstallReferrer()` | Get raw Play Install Referrer data (Android) |
|
|
624
1086
|
|
|
625
1087
|
---
|
|
626
1088
|
|
package/lib/datalyr-sdk.js
CHANGED
|
@@ -23,7 +23,7 @@ export class DatalyrSDK {
|
|
|
23
23
|
workspaceId: '',
|
|
24
24
|
apiKey: '',
|
|
25
25
|
debug: false,
|
|
26
|
-
endpoint: 'https://
|
|
26
|
+
endpoint: 'https://ingest.datalyr.com/track',
|
|
27
27
|
useServerTracking: true, // Default to server-side
|
|
28
28
|
maxRetries: 3,
|
|
29
29
|
retryDelay: 1000,
|
|
@@ -63,7 +63,7 @@ export class DatalyrSDK {
|
|
|
63
63
|
// Set up configuration
|
|
64
64
|
this.state.config = { ...this.state.config, ...config };
|
|
65
65
|
// Initialize HTTP client with server-side API
|
|
66
|
-
this.httpClient = new HttpClient(this.state.config.endpoint || 'https://
|
|
66
|
+
this.httpClient = new HttpClient(this.state.config.endpoint || 'https://ingest.datalyr.com/track', {
|
|
67
67
|
maxRetries: this.state.config.maxRetries || 3,
|
|
68
68
|
retryDelay: this.state.config.retryDelay || 1000,
|
|
69
69
|
timeout: this.state.config.timeout || 15000,
|
|
@@ -347,10 +347,9 @@ export class DatalyrSDK {
|
|
|
347
347
|
}
|
|
348
348
|
try {
|
|
349
349
|
debugLog('Fetching deferred web attribution via IP matching...');
|
|
350
|
-
const baseUrl = this.state.config.endpoint || 'https://api.datalyr.com';
|
|
351
350
|
const controller = new AbortController();
|
|
352
351
|
const timeout = setTimeout(() => controller.abort(), 10000);
|
|
353
|
-
const response = await fetch(
|
|
352
|
+
const response = await fetch('https://api.datalyr.com/attribution/deferred-lookup', {
|
|
354
353
|
method: 'POST',
|
|
355
354
|
headers: {
|
|
356
355
|
'Content-Type': 'application/json',
|
package/lib/http-client.js
CHANGED
|
@@ -5,7 +5,7 @@ export class HttpClient {
|
|
|
5
5
|
this.requestCount = 0;
|
|
6
6
|
// Use server-side API if flag is set (default to true for v1.0.0)
|
|
7
7
|
this.endpoint = config.useServerTracking !== false
|
|
8
|
-
? 'https://
|
|
8
|
+
? 'https://ingest.datalyr.com/track'
|
|
9
9
|
: endpoint;
|
|
10
10
|
this.config = config;
|
|
11
11
|
}
|
package/lib/types.d.ts
CHANGED
|
@@ -42,11 +42,11 @@ export interface DatalyrConfig {
|
|
|
42
42
|
/** Enable console logging for debugging. Default: false */
|
|
43
43
|
debug?: boolean;
|
|
44
44
|
/**
|
|
45
|
-
* API endpoint URL. Default: 'https://
|
|
45
|
+
* API endpoint URL. Default: 'https://ingest.datalyr.com/track'
|
|
46
46
|
* @deprecated Use `endpoint` instead
|
|
47
47
|
*/
|
|
48
48
|
apiUrl?: string;
|
|
49
|
-
/** API endpoint URL. Default: 'https://
|
|
49
|
+
/** API endpoint URL. Default: 'https://ingest.datalyr.com/track' */
|
|
50
50
|
endpoint?: string;
|
|
51
51
|
/** Use server-side tracking. Default: true */
|
|
52
52
|
useServerTracking?: boolean;
|
package/package.json
CHANGED
package/src/datalyr-sdk-expo.ts
CHANGED
|
@@ -55,7 +55,7 @@ export class DatalyrSDKExpo {
|
|
|
55
55
|
workspaceId: '',
|
|
56
56
|
apiKey: '',
|
|
57
57
|
debug: false,
|
|
58
|
-
endpoint: 'https://
|
|
58
|
+
endpoint: 'https://ingest.datalyr.com/track',
|
|
59
59
|
useServerTracking: true,
|
|
60
60
|
maxRetries: 3,
|
|
61
61
|
retryDelay: 1000,
|
|
@@ -92,7 +92,7 @@ export class DatalyrSDKExpo {
|
|
|
92
92
|
|
|
93
93
|
this.state.config = { ...this.state.config, ...config };
|
|
94
94
|
|
|
95
|
-
this.httpClient = new HttpClient(this.state.config.endpoint || 'https://
|
|
95
|
+
this.httpClient = new HttpClient(this.state.config.endpoint || 'https://ingest.datalyr.com/track', {
|
|
96
96
|
maxRetries: this.state.config.maxRetries || 3,
|
|
97
97
|
retryDelay: this.state.config.retryDelay || 1000,
|
|
98
98
|
timeout: this.state.config.timeout || 15000,
|
package/src/datalyr-sdk.ts
CHANGED
|
@@ -54,7 +54,7 @@ export class DatalyrSDK {
|
|
|
54
54
|
workspaceId: '',
|
|
55
55
|
apiKey: '',
|
|
56
56
|
debug: false,
|
|
57
|
-
endpoint: 'https://
|
|
57
|
+
endpoint: 'https://ingest.datalyr.com/track',
|
|
58
58
|
useServerTracking: true, // Default to server-side
|
|
59
59
|
maxRetries: 3,
|
|
60
60
|
retryDelay: 1000,
|
|
@@ -99,7 +99,7 @@ export class DatalyrSDK {
|
|
|
99
99
|
this.state.config = { ...this.state.config, ...config };
|
|
100
100
|
|
|
101
101
|
// Initialize HTTP client with server-side API
|
|
102
|
-
this.httpClient = new HttpClient(this.state.config.endpoint || 'https://
|
|
102
|
+
this.httpClient = new HttpClient(this.state.config.endpoint || 'https://ingest.datalyr.com/track', {
|
|
103
103
|
maxRetries: this.state.config.maxRetries || 3,
|
|
104
104
|
retryDelay: this.state.config.retryDelay || 1000,
|
|
105
105
|
timeout: this.state.config.timeout || 15000,
|
|
@@ -425,11 +425,10 @@ export class DatalyrSDK {
|
|
|
425
425
|
try {
|
|
426
426
|
debugLog('Fetching deferred web attribution via IP matching...');
|
|
427
427
|
|
|
428
|
-
const baseUrl = this.state.config.endpoint || 'https://api.datalyr.com';
|
|
429
428
|
const controller = new AbortController();
|
|
430
429
|
const timeout = setTimeout(() => controller.abort(), 10000);
|
|
431
430
|
|
|
432
|
-
const response = await fetch(
|
|
431
|
+
const response = await fetch('https://api.datalyr.com/attribution/deferred-lookup', {
|
|
433
432
|
method: 'POST',
|
|
434
433
|
headers: {
|
|
435
434
|
'Content-Type': 'application/json',
|
package/src/http-client.ts
CHANGED
|
@@ -26,8 +26,8 @@ export class HttpClient {
|
|
|
26
26
|
|
|
27
27
|
constructor(endpoint: string, config: HttpClientConfig) {
|
|
28
28
|
// Use server-side API if flag is set (default to true for v1.0.0)
|
|
29
|
-
this.endpoint = config.useServerTracking !== false
|
|
30
|
-
? 'https://
|
|
29
|
+
this.endpoint = config.useServerTracking !== false
|
|
30
|
+
? 'https://ingest.datalyr.com/track'
|
|
31
31
|
: endpoint;
|
|
32
32
|
this.config = config;
|
|
33
33
|
}
|
package/src/types.ts
CHANGED
|
@@ -49,12 +49,12 @@ export interface DatalyrConfig {
|
|
|
49
49
|
debug?: boolean;
|
|
50
50
|
|
|
51
51
|
/**
|
|
52
|
-
* API endpoint URL. Default: 'https://
|
|
52
|
+
* API endpoint URL. Default: 'https://ingest.datalyr.com/track'
|
|
53
53
|
* @deprecated Use `endpoint` instead
|
|
54
54
|
*/
|
|
55
55
|
apiUrl?: string;
|
|
56
56
|
|
|
57
|
-
/** API endpoint URL. Default: 'https://
|
|
57
|
+
/** API endpoint URL. Default: 'https://ingest.datalyr.com/track' */
|
|
58
58
|
endpoint?: string;
|
|
59
59
|
|
|
60
60
|
/** Use server-side tracking. Default: true */
|