Skip to content

dynalinks/dynalinks-react-native-sdk

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

7 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

expo-dynalinks-sdk

The official React Native SDK for Dynalinks - deferred deep linking and attribution for iOS and Android apps.

Features

  • Deferred Deep Linking: Track users who click links before installing your app
  • Manual Link Resolution: Resolve Dynalinks URLs to link data
  • Cross-Platform: Single API for both iOS and Android
  • Type-Safe: Full TypeScript support with comprehensive error handling

Requirements

  • React Native 0.70.0 or later
  • Expo SDK 49 or later
  • iOS 16.0 or later
  • Android API 21 or later

Installation

npx expo install expo-dynalinks-sdk

Setup

iOS Setup

  1. Register your iOS app in the Dynalinks Console:

    • Bundle Identifier (from Xcode project settings)
    • Team ID (from Apple Developer account)
    • App Store ID (from your app's App Store URL)
  2. Configure Associated Domains in Xcode:

    • Open your iOS project > Signing & Capabilities
    • Add the "Associated Domains" capability
    • Add your domain: applinks:yourproject.dynalinks.app

See the iOS integration guide for detailed instructions.

Android Setup

  1. Register your Android app in the Dynalinks Console:

    • Package identifier (from build.gradle applicationId)
    • SHA-256 certificate fingerprint (run ./gradlew signingReport)
  2. Add intent filter to your AndroidManifest.xml:

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

    <intent-filter android:autoVerify="true">
        <action android:name="android.intent.action.VIEW" />
        <category android:name="android.intent.category.DEFAULT" />
        <category android:name="android.intent.category.BROWSABLE" />
        <data
            android:scheme="https"
            android:host="yourproject.dynalinks.app" />
    </intent-filter>
</activity>

See the Android integration guide for detailed instructions.

Usage

Initialize the SDK

Configure the SDK as early as possible in your app's lifecycle:

import Dynalinks, { DynalinksLogLevel } from 'expo-dynalinks-sdk';

// In your App.tsx or index.js
await Dynalinks.configure({
  clientAPIKey: 'your-client-api-key',
  logLevel: DynalinksLogLevel.debug, // Use .error in production
});

Check for Deferred Deep Links

Check if the user came from a Dynalinks link before installing:

import Dynalinks from 'expo-dynalinks-sdk';

async function checkDeferredDeepLink() {
  try {
    const result = await Dynalinks.checkForDeferredDeepLink();

    if (result.matched && result.link?.deepLinkValue) {
      // User came from a deep link - navigate accordingly
      navigation.navigate(result.link.deepLinkValue);
    }
  } catch (error) {
    if (error.code === 'SIMULATOR') {
      // Running on simulator - deferred deep linking not available
    } else {
      console.error('Error checking deferred deep link:', error);
    }
  }
}

Handle Incoming Deep Links

Use React Native's built-in Linking API to capture URLs, then resolve them with Dynalinks:

import { useEffect } from 'react';
import { Linking } from 'react-native';
import Dynalinks from 'expo-dynalinks-sdk';

function App() {
  useEffect(() => {
    // Listen for links while app is running
    const subscription = Linking.addEventListener('url', async (event) => {
      const result = await Dynalinks.resolveLink(event.url);

      if (result.matched && result.link?.deepLinkValue) {
        navigation.navigate(result.link.deepLinkValue);
      }
    });

    return () => subscription.remove();
  }, []);

  return <YourApp />;
}

Complete Example

import { useEffect } from 'react';
import { Linking } from 'react-native';
import Dynalinks, { DynalinksLogLevel } from 'expo-dynalinks-sdk';

function App() {
  useEffect(() => {
    let subscription: ReturnType<typeof Linking.addEventListener> | undefined;

    async function initializeDynalinks() {
      try {
        // 1. Configure SDK
        await Dynalinks.configure({
          clientAPIKey: 'your-api-key',
          logLevel: DynalinksLogLevel.debug,
        });

        // 2. Check for deferred deep link
        const result = await Dynalinks.checkForDeferredDeepLink();
        if (result.matched) {
          handleDeepLink(result.link?.deepLinkValue);
        }

        // 3. Listen for incoming links
        subscription = Linking.addEventListener('url', async (event) => {
          const result = await Dynalinks.resolveLink(event.url);
          if (result.matched) {
            handleDeepLink(result.link?.deepLinkValue);
          }
        });
      } catch (error) {
        console.error('Dynalinks initialization error:', error);
      }
    }

    initializeDynalinks();

    // Clean up on unmount
    return () => subscription?.remove();
  }, []);

  function handleDeepLink(deepLinkValue?: string) {
    if (!deepLinkValue) return;

    // Navigate based on deep link value
    // Example: Use your navigation library (e.g., React Navigation)
    if (deepLinkValue.startsWith('product/')) {
      const productId = deepLinkValue.replace('product/', '');
      // navigation.navigate('ProductDetails', { productId });
    }
  }

  return <YourApp />;
}

API Reference

Dynalinks

Method Description
configure(config) Initialize the SDK with your API key
checkForDeferredDeepLink() Check for deferred deep link (first launch)
resolveLink(url) Resolve a URL to link data
version SDK version string

DeepLinkResult

Property Type Description
matched boolean Whether a link was matched
confidence 'high' | 'medium' | 'low' Match confidence
matchScore number Match score (0-100)
link LinkData The matched link data
isDeferred boolean Whether from deferred deep link

LinkData

Property Type Description
id string Unique link identifier
name string Link name (for display)
path string Link path
shortenedPath string Shortened path
url string Original URL the link points to
fullUrl string Full Dynalinks URL
deepLinkValue string Value for in-app navigation
iosDeferredDeepLinkingEnabled boolean Whether iOS deferred deep linking is enabled (iOS only)
referrer string Referrer tracking parameter (e.g., "utm_source=facebook")
providerToken string Apple Search Ads attribution token
campaignToken string Campaign identifier for attribution
iosFallbackUrl string iOS fallback URL
androidFallbackUrl string Android fallback URL
enableForcedRedirect boolean Whether forced redirect is enabled
socialTitle string Social sharing title
socialDescription string Social sharing description
socialImageUrl string Social sharing image
clicks number Number of clicks on this link

Exceptions

Exception Description
NotConfiguredError SDK not configured
InvalidApiKeyError Invalid API key format
InvalidConfigError Invalid configuration (e.g., baseURL)
SimulatorError Running on simulator/emulator
NetworkError Network request failed
ServerError Server returned an error
InvalidResponseError Invalid server response
NoMatchError No matching link found
InvalidUrlError Invalid URL format
InstallReferrerUnavailableError Install referrer unavailable (Android)
InstallReferrerTimeoutError Install referrer timeout (Android)

Configuration Options

await Dynalinks.configure({
  clientAPIKey: 'your-api-key',     // Required
  logLevel: DynalinksLogLevel.debug, // Optional, default: .error
  allowSimulator: false,             // Optional, default: false
});

Log Levels

  • DynalinksLogLevel.none - No logging
  • DynalinksLogLevel.error - Errors only (default)
  • DynalinksLogLevel.warning - Warnings and errors
  • DynalinksLogLevel.info - Info, warnings, and errors
  • DynalinksLogLevel.debug - All logs

Attribution Tracking

The SDK provides attribution tracking fields for analytics and campaign measurement:

const result = await Dynalinks.checkForDeferredDeepLink();

if (result.matched && result.link) {
  // Access attribution data
  console.log('Referrer:', result.link.referrer);           // UTM parameters
  console.log('Provider Token:', result.link.providerToken); // Apple Search Ads
  console.log('Campaign Token:', result.link.campaignToken); // Campaign ID

  // Send to your analytics
  analytics.track('deep_link_attribution', {
    referrer: result.link.referrer,
    campaign: result.link.campaignToken,
    provider: result.link.providerToken,
  });
}

Migration from v0.1.0

Before (v0.1.0):

import { configureDynalinks, addDeferredDeepLinkListener } from 'expo-dynalinks-sdk';

const subscription = addDeferredDeepLinkListener((event) => {
  if (event.matched) {
    navigate(event.link?.deep_link_value);
  }
});

await configureDynalinks('api-key');

After (v1.0.0):

import Dynalinks from 'expo-dynalinks-sdk';

await Dynalinks.configure({ clientAPIKey: 'api-key' });

const result = await Dynalinks.checkForDeferredDeepLink();
if (result.matched && result.link?.deepLinkValue) {
  navigate(result.link.deepLinkValue);
}

Support

License

This project is licensed under the MIT License - see the LICENSE file for details.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Packages

No packages published

Languages

  • TypeScript 44.8%
  • Swift 23.7%
  • Kotlin 22.2%
  • JavaScript 5.3%
  • Ruby 4.0%