@mantiqh/deferred-links-react-native
v1.0.5
Published
React Native SDK for the Lite Deferred Deep Linking Platform
Readme
React Native SDK - Lite Deferred Deep Linking
A lightweight React Native SDK designed to perform deferred deep link resolution on first app launch. It integrates platform-native APIs (such as Google Play Install Referrer), clipboard snooping, and IP-based fallback to automatically resolve attribution.
Installation
Install the package:
npm install @mantiqh/deferred-links-react-nativePeer Dependencies
This SDK requires the following packages to be installed in your consuming React Native app. Install them according to your package manager:
npm install @react-native-async-storage/async-storage @react-native-clipboard/clipboard react-native-play-install-referrer[!IMPORTANT]
- Native Dependencies:
react-native-play-install-referrercontains native Android code. Consequently, this library is not compatible with Expo Go out of the box and requires a development build (npx expo run:androidor custom native configurations).- iOS CocoaPods: After installing the dependencies, run
pod installin youriosdirectory.
Attribution Resolution Flow
On startup, calling getAttributionData executes the following checks in strict priority order to resolve the referral metadata:
| Priority | Source | Reliability | Platform | Notes | |---|---|---|---|---| | 1 | Google Play Install Referrer | Deterministic | Android only | Directly fetched from the Play Store API; immune to user spoofing. | | 2 | Clipboard check | Deterministic | iOS & Android | Relies on the interstitial page writing the link/slug to the clipboard. Note: Under iOS 16+, reading the clipboard triggers a system permission popup. | | 3 | IP-Based Fallback | Probabilistic | iOS & Android | Matches client IP + OS version + device locale against the Redis click cache. |
Usage
Run the resolution flow as early as possible in your application lifecycle (e.g., in your root App.tsx component or entry point).
Comprehensive Example
import React, { useEffect, useState } from 'react';
import { View, Text, ActivityIndicator, StyleSheet } from 'react-native';
import { getAttributionData, getStoredMetadata, AttributionMetadata } from '@mantiqh/deferred-links-react-native';
const CORE_SERVICE_URL = 'https://core.yourdomain.com';
const SHORT_LINK_DOMAIN = 'lnk.yourdomain.com';
export default function App() {
const [loading, setLoading] = useState(true);
const [attribution, setAttribution] = useState<AttributionMetadata | null>(null);
useEffect(() => {
async function initAttribution() {
try {
// 1. Try to read previously resolved metadata from storage
let metadata = await getStoredMetadata();
// 2. If not already resolved, trigger the attribution flow
if (!metadata) {
metadata = await getAttributionData(CORE_SERVICE_URL, SHORT_LINK_DOMAIN);
}
setAttribution(metadata);
} catch (error) {
console.error('Failed to resolve attribution:', error);
} finally {
setLoading(false);
}
}
initAttribution();
}, []);
if (loading) {
return (
<View style={styles.center}>
<ActivityIndicator size="large" color="#007aff" />
</View>
);
}
return (
<View style={styles.center}>
{attribution ? (
<View style={styles.card}>
<Text style={styles.title}>Attribution Resolved!</Text>
<Text style={styles.text}>Referrer ID: {attribution.referrerId}</Text>
<Text style={styles.text}>Campaign: {attribution.campaign}</Text>
<Text style={styles.source}>Matched via: {attribution.source}</Text>
</View>
) : (
<Text style={styles.text}>Organic Installation (No referral metadata found)</Text>
)}
</View>
);
}
const styles = StyleSheet.create({
center: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
backgroundColor: '#f5f7fa',
},
card: {
padding: 24,
borderRadius: 12,
backgroundColor: '#ffffff',
shadowColor: '#000',
shadowOpacity: 0.1,
shadowOffset: { width: 0, height: 2 },
shadowRadius: 8,
elevation: 3,
alignItems: 'center',
},
title: {
fontSize: 20,
fontWeight: 'bold',
marginBottom: 12,
color: '#333',
},
text: {
fontSize: 16,
color: '#666',
marginVertical: 4,
},
source: {
marginTop: 12,
fontSize: 12,
color: '#007aff',
fontWeight: '600',
textTransform: 'uppercase',
}
});API Reference
getAttributionData(baseUrl: string, domain: string): Promise<AttributionMetadata | null>
Checks if attribution was already resolved. If not, it executes the Android Install Referrer, Clipboard, and IP-Based probabilistic matching steps.
baseUrl: The endpoint where the Core Redirect Service is hosted (e.g.https://core.yourdomain.com).domain: The domain name used for generating short links (e.g.lnk.yourdomain.com).- Returns: A promise that resolves to
AttributionMetadataif matched, ornullif the installation is organic or already resolved.
getStoredMetadata(): Promise<AttributionMetadata | null>
A convenience method that reads and returns previously resolved metadata directly from AsyncStorage.
- Returns: A promise resolving to
AttributionMetadata | null.
Storage Footprint
The SDK persists the following key-value pairs in AsyncStorage:
ddl_attribution_resolved: Set to'true'once the resolution flow completes (preventing subsequent startup checks from resolving again).ddl_metadata: JSON string containing the resolved metadata, plus asourcefield indicating how it was resolved (play_referrer,clipboard, orip_fallback).
