Skip to main content

React Native SDK

Integrate deferred deep linking and mobile attribution into your React Native app with the LinkForty SDK.

Features

  • Deferred Deep Linking - Route new users to specific content after install
  • Direct Deep Linking - Handle links for existing users
  • Attribution Tracking - Track which links drive installs
  • Event Tracking - Log in-app events with attribution
  • Fingerprint Matching - 70%+ attribution accuracy
  • TypeScript Support - Full type definitions included
  • Cross-Platform - iOS and Android with single codebase

Installation

1. Install Package

npm install @linkforty/mobile-sdk-react-native

or

yarn add @linkforty/mobile-sdk-react-native

2. Install Peer Dependencies

The SDK requires these peer dependencies:

npm install @react-native-async-storage/async-storage react-native-device-info

For React Native 0.60+: Auto-linking handles this automatically.

For React Native < 0.60:

react-native link @linkforty/mobile-sdk-react-native
react-native link @react-native-async-storage/async-storage
react-native link react-native-device-info

4. iOS Setup

cd ios && pod install && cd ..

Add to ios/YourApp/Info.plist:

<key>LSApplicationQueriesSchemes</key>
<array>
<string>linkforty</string>
</array>

<key>CFBundleURLTypes</key>
<array>
<dict>
<key>CFBundleURLSchemes</key>
<array>
<string>yourapp</string>
</array>
</dict>
</array>

5. Android Setup

Add to android/app/src/main/AndroidManifest.xml:

<activity
android:name=".MainActivity"
android:launchMode="singleTask">

<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="yourapp" />
</intent-filter>
</activity>

Quick Start

1. Initialize SDK

In your App.tsx or App.js:

import React, { useEffect } from 'react';
import { LinkFortySDK } from '@linkforty/mobile-sdk-react-native';

function App() {
useEffect(() => {
// Initialize SDK on app launch
LinkFortySDK.init({
baseUrl: 'https://your-linkforty-domain.com', // Your LinkForty instance URL
apiKey: 'your-api-key', // Optional for cloud, required for some features
debug: __DEV__, // Enable debug logs in development
});
}, []);

return (
// Your app components
);
}

export default App;
import React, { useEffect } from 'react';
import { LinkFortySDK, DeepLinkData } from '@linkforty/mobile-sdk-react-native';
import { useNavigation } from '@react-navigation/native';

function App() {
const navigation = useNavigation();

useEffect(() => {
// Initialize SDK
LinkFortySDK.init({
baseUrl: 'https://your-linkforty-domain.com',
apiKey: 'your-api-key',
});

// Set up deep link listeners
setupDeepLinkHandlers();
}, []);

const setupDeepLinkHandlers = () => {
// Handle deferred deep links (new installs)
LinkFortySDK.onDeferredDeepLink((data: DeepLinkData) => {
console.log('Deferred deep link:', data);
handleDeepLinkData(data);
});

// Handle direct deep links (app already installed)
LinkFortySDK.onDeepLink((data: DeepLinkData) => {
console.log('Direct deep link:', data);
handleDeepLinkData(data);
});
};

const handleDeepLinkData = (data: DeepLinkData) => {
// Access custom parameters from the link
const productId = data.customParameters?.productId;
const screen = data.customParameters?.screen;

// Access UTM parameters
const utmSource = data.utmParameters?.utm_source;

if (productId) {
navigation.navigate('Product', { id: productId });
} else if (screen) {
navigation.navigate(screen);
}
};

return (
// Your app components
);
}

3. Track Events

import { LinkFortySDK } from '@linkforty/mobile-sdk-react-native';

// Track purchase
LinkFortySDK.trackEvent('purchase', {
value: 29.99,
currency: 'USD',
productId: '123',
productName: 'Wireless Headphones',
quantity: 1
});

// Track registration
LinkFortySDK.trackEvent('signup', {
method: 'email'
});

// Track custom event
LinkFortySDK.trackEvent('level_completed', {
level: 5,
score: 1250
});

Configuration Options

Init Options

interface LinkFortyConfig {
baseUrl: string; // Required: Your LinkForty instance URL
apiKey?: string; // Optional: API key for authentication
debug?: boolean; // Optional: Enable debug logs (default: false)
attributionWindow?: number; // Optional: Attribution window in days (default: 7)
}

LinkFortySDK.init({
baseUrl: 'https://your-linkforty-domain.com',
apiKey: 'your-api-key',
debug: __DEV__,
attributionWindow: 7
});

Self-Hosted Configuration

If you're self-hosting LinkForty:

LinkFortySDK.init({
baseUrl: 'https://your-domain.com', // Your self-hosted URL
apiKey: 'your-api-key',
debug: false
});

Deep Linking

Create links via dashboard or API that include deep link parameters:

curl -X POST https://your-linkforty-domain.com/api/links \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"templateId": "550e8400-e29b-41d4-a716-446655440000",
"originalUrl": "https://example.com/products/123?productId=123&utm_source=instagram",
"iosUrl": "https://apps.apple.com/app/id123456789",
"androidUrl": "https://play.google.com/store/apps/details?id=com.yourapp"
}'

Deep Link Parameters:

  • Query parameters in originalUrl become available in customParameters
  • UTM parameters are automatically extracted to utmParameters
  • Example: ?productId=123&category=electronics&utm_source=instagram

DeepLinkData Structure

The DeepLinkData object contains:

interface DeepLinkData {
shortCode: string; // The short link code
iosUrl?: string; // iOS app store URL
androidUrl?: string; // Android play store URL
webUrl?: string; // Web fallback URL
utmParameters?: { // UTM tracking parameters
utm_source?: string;
utm_medium?: string;
utm_campaign?: string;
utm_term?: string;
utm_content?: string;
};
customParameters?: { // Custom parameters from link URL
[key: string]: string;
};
clickedAt?: string; // When the link was clicked
linkId?: string; // Unique link identifier
}

Deferred Deep Linking (new installs):

useEffect(() => {
// Register callback for deferred deep links
LinkFortySDK.onDeferredDeepLink((data: DeepLinkData) => {
// User clicked a link before installing
console.log('Deferred deep link:', data);

// Example data structure:
// {
// shortCode: "abc123",
// customParameters: {
// productId: "123",
// category: "electronics"
// },
// utmParameters: {
// utm_source: "instagram",
// utm_campaign: "spring-sale"
// }
// }

// Navigate to product
if (data.customParameters?.productId) {
navigation.navigate('Product', { id: data.customParameters.productId });
}
});
}, []);

Direct Deep Linking (existing users):

useEffect(() => {
// Register callback for direct deep links
LinkFortySDK.onDeepLink((data: DeepLinkData) => {
console.log('Direct deep link:', data);

if (data.customParameters?.productId) {
navigation.navigate('Product', { id: data.customParameters.productId });
}
});
}, []);

Handle both deferred and direct deep links:

import React, { useEffect } from 'react';
import { LinkFortySDK, DeepLinkData } from '@linkforty/mobile-sdk-react-native';
import { useNavigation } from '@react-navigation/native';

function App() {
const navigation = useNavigation();

useEffect(() => {
// Initialize SDK
LinkFortySDK.init({
baseUrl: 'https://your-linkforty-domain.com',
apiKey: 'your-api-key',
debug: __DEV__,
});

// Handle deferred deep links (new installs)
LinkFortySDK.onDeferredDeepLink((data: DeepLinkData) => {
console.log('Deferred deep link:', data);
handleDeepLinkData(data);
});

// Handle direct deep links (existing users)
LinkFortySDK.onDeepLink((data: DeepLinkData) => {
console.log('Direct deep link:', data);
handleDeepLinkData(data);
});
}, []);

const handleDeepLinkData = (data: DeepLinkData) => {
// Extract routing info from customParameters
const route = data.customParameters?.route;
const productId = data.customParameters?.productId;
const screen = data.customParameters?.screen;

if (productId) {
navigation.navigate('Product', { id: productId });
} else if (route) {
navigation.navigate(route, data.customParameters);
} else if (screen) {
navigation.navigate(screen);
}
};

return (
// Your app
);
}

Event Tracking

Track Events with Attribution

import { LinkFortySDK } from '@linkforty/mobile-sdk-react-native';

// Purchase event
LinkFortySDK.trackEvent('purchase', {
value: 49.99,
currency: 'USD',
productId: '123',
productName: 'Wireless Headphones',
category: 'Electronics',
quantity: 1
});

// Add to cart
LinkFortySDK.trackEvent('add_to_cart', {
value: 49.99,
currency: 'USD',
productId: '123',
source: 'product_page'
});

// User registration
LinkFortySDK.trackEvent('signup', {
method: 'email',
referralCode: 'FRIEND123'
});

// Custom event
LinkFortySDK.trackEvent('tutorial_completed', {
duration_seconds: 120,
steps_completed: 5
});

Standard Events

Recommended event names for common actions:

Event NameDescriptionProperties
purchaseUser completes purchasevalue, currency, productId
add_to_cartItem added to cartproductId, value
begin_checkoutCheckout startedvalue, currency
signupUser registersmethod (email, social, etc.)
loginUser logs inmethod
view_contentContent viewedcontentType, contentId
searchUser searchesquery, results
shareContent sharedcontentType, method
level_completedGame level completedlevel, score
achievement_unlockedAchievement earnedachievement_id

API Reference

init()

Initialize the SDK. Call once on app launch.

LinkFortySDK.init(config: LinkFortyConfig): Promise<void>

Parameters:

{
baseUrl: string; // Your LinkForty instance URL
apiKey?: string; // API key for authentication
debug?: boolean; // Enable debug logs (default: false)
attributionWindow?: number; // Attribution window in days (default: 7)
}

Example:

await LinkFortySDK.init({
baseUrl: 'https://your-linkforty-domain.com',
apiKey: 'your-api-key',
debug: __DEV__
});

Register a callback for deferred deep links (new installs).

LinkFortySDK.onDeferredDeepLink(callback: (data: DeepLinkData) => void): void

Example:

LinkFortySDK.onDeferredDeepLink((data) => {
console.log('User installed from link:', data);
if (data.customParameters?.productId) {
navigation.navigate('Product', { id: data.customParameters.productId });
}
});

Register a callback for direct deep links (existing users).

LinkFortySDK.onDeepLink(callback: (data: DeepLinkData) => void): void

Example:

LinkFortySDK.onDeepLink((data) => {
console.log('Deep link received:', data);
if (data.customParameters?.productId) {
navigation.navigate('Product', { id: data.customParameters.productId });
}
});

trackEvent()

Track custom events with attribution.

LinkFortySDK.trackEvent(eventName: string, properties?: Record<string, any>): void

Parameters:

  • eventName - Name of the event
  • properties - Optional object with event properties

Example:

LinkFortySDK.trackEvent('purchase', {
value: 29.99,
currency: 'USD',
productId: '123',
category: 'Electronics'
});

getInstallId()

Get the unique installation identifier.

LinkFortySDK.getInstallId(): Promise<string | null>

Example:

const installId = await LinkFortySDK.getInstallId();
console.log('Install ID:', installId);

getInstallData()

Retrieve cached attribution information.

LinkFortySDK.getInstallData(): Promise<DeepLinkData | null>

Example:

const installData = await LinkFortySDK.getInstallData();
if (installData) {
console.log('Attribution data:', installData);
}

clearData()

Clear all cached SDK data.

LinkFortySDK.clearData(): Promise<void>

Example:

// On user logout or data reset
await LinkFortySDK.clearData();

Complete Example

E-commerce App

import React, { useEffect, useState } from 'react';
import { View, Text, Button } from 'react-native';
import { LinkFortySDK, DeepLinkData } from '@linkforty/mobile-sdk-react-native';
import { NavigationContainer, useNavigation } from '@react-navigation/native';
import { createNativeStackNavigator } from '@react-navigation/native-stack';

const Stack = createNativeStackNavigator();

function App() {
useEffect(() => {
initializeLinkForty();
}, []);

const initializeLinkForty = async () => {
// Initialize SDK
await LinkFortySDK.init({
baseUrl: 'https://your-linkforty-domain.com',
apiKey: 'your-api-key',
debug: __DEV__
});

// Handle deferred deep links (new installs)
LinkFortySDK.onDeferredDeepLink((data: DeepLinkData) => {
console.log('User installed from link:', data);
handleDeepLink(data);
});

// Handle direct deep links (existing users)
LinkFortySDK.onDeepLink((data: DeepLinkData) => {
console.log('Deep link received:', data);
handleDeepLink(data);
});
};

const handleDeepLink = (data: DeepLinkData) => {
if (data.customParameters?.productId) {
// Navigate after a short delay to ensure navigation is ready
setTimeout(() => {
navigation.navigate('Product', { id: data.customParameters.productId });
}, 100);
}
};

return (
<NavigationContainer>
<Stack.Navigator>
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Product" component={ProductScreen} />
<Stack.Screen name="Cart" component={CartScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}

function ProductScreen({ route }) {
const { id } = route.params;
const [product, setProduct] = useState(null);

useEffect(() => {
// Load product data
loadProduct(id);

// Track product view
LinkFortySDK.trackEvent('view_content', {
contentType: 'product',
contentId: id
});
}, [id]);

const handleAddToCart = () => {
// Track add to cart
LinkFortySDK.trackEvent('add_to_cart', {
value: product.price,
currency: 'USD',
productId: id,
productName: product.name
});

// Add to cart logic...
};

const handlePurchase = () => {
// Track purchase
LinkFortySDK.trackEvent('purchase', {
value: product.price,
currency: 'USD',
productId: id,
productName: product.name,
category: product.category
});

// Complete purchase...
};

return (
<View>
<Text>{product?.name}</Text>
<Text>${product?.price}</Text>
<Button title="Add to Cart" onPress={handleAddToCart} />
<Button title="Buy Now" onPress={handlePurchase} />
</View>
);
}

export default App;

Troubleshooting

Symptoms:

  • onDeferredDeepLink or onDeepLink callbacks never fire
  • User definitely clicked a link before installing

Possible Causes:

  1. Attribution window expired

    • Check link's attribution window setting
    • User may have installed too long after clicking
  2. Fingerprint mismatch

    • Different WiFi network for click vs install
    • VPN or proxy usage
    • iOS 14+ privacy features
  3. SDK not initialized

    • Verify init() is called before registering callbacks
  4. Wrong API key or base URL

    • Check the configuration is correct
    • Verify it's for the right environment

Solutions:

// Enable debug logging to troubleshoot
await LinkFortySDK.init({
baseUrl: 'https://your-linkforty-domain.com',
apiKey: 'your-api-key',
debug: true // Enable verbose logging
});

// Register callbacks after init
LinkFortySDK.onDeferredDeepLink((data) => {
console.log('Deferred deep link data:', JSON.stringify(data, null, 2));
});

Events Not Tracking

Symptoms:

  • trackEvent() called but events don't appear in analytics

Possible Causes:

  1. Network connectivity issues
  2. Invalid API key
  3. SDK not initialized

Solutions:

// Ensure SDK is initialized first
await LinkFortySDK.init({ ... });

// Then track events
LinkFortySDK.trackEvent('purchase', {
value: 29.99
});
console.log('Event tracked');

iOS Build Errors

Symptoms:

  • Build fails after installing SDK

Solution:

cd ios
pod deintegrate
pod install
cd ..

Android Build Errors

Symptoms:

  • Build fails with dependency conflicts

Solution: Ensure your android/build.gradle has the correct minSdkVersion:

minSdkVersion = 21

TypeScript Types

The SDK exports these TypeScript types:

import {
LinkFortySDK,
DeepLinkData,
LinkFortyConfig
} from '@linkforty/mobile-sdk-react-native';

Next Steps

Support