React Native

GitHub tag (latest by date)GitHub tag (latest by date)

Configure Branch

Install Branch

via Pure React Native App

Expo Note: If you are working with Expo, you must first eject your app from Expo, use the Expo Bare Workflow and follow the instructions below.

expo eject

Note: react-native-branch requires react-native >= 0.60

  • Install the module

via Native iOS app with CocoaPods

CocoaPods

platform :ios, '9.0'

target 'APP_NAME' do
  # if swift
  use_frameworks!

  pod 'react-native-branch', path: '../node_modules/react-native-branch'
end
  • Run pod install to regenerate the Pods project with the new dependencies. Note that the location of node_modules relative to your Podfile may vary.

📘

(Optional) Add a branch.json file to the root of your app (next to package.json).

You can configure the contents at any time, but it must be present when you run react-native link in order to be automatically included in your native projects. This allows you to configure certain behaviors that otherwise require native code changes. See https://rnbranch.app.link/branch-json for full details on the branch.json file.

Configure App

iOS

Android

Initialize Branch

iOS

  • In your app's AppDelegate file:
import RNBranch

@UIApplicationMain
class AppDelegate: UIResponder, UIApplicationDelegate {
  
// Initialize the Branch Session at the top of existing application:didFinishLaunchingWithOptions:
func application(_ application: UIApplication, didFinishLaunchingWithOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool {
  // Uncomment this line to use the test key instead of the live one.
  // RNBranch.useTestInstance()
  RNBranch.initSession(launchOptions: launchOptions)
  
  return true
}

// Add the openURL and continueUserActivity functions
func application(_ app: UIApplication, open url: URL, options: [UIApplicationOpenURLOptionsKey : Any] = [:]) -> Bool {
  return RNBranch.application(app, open:url, options:options)
}

func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([Any]?) -> Void) -> Bool {
  return RNBranch.continue(userActivity)
}
#import "AppDelegate.h"
#import <RNBranch/RNBranch.h>
  
@implementation AppDelegate
  
// Initialize the Branch Session at the top of existing application:didFinishLaunchingWithOptions:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // Uncomment this line to use the test key instead of the live one.
    // [RNBranch useTestInstance];
    [RNBranch initSessionWithLaunchOptions:launchOptions]; 
    NSURL *jsCodeLocation;
    //...
}

- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options {
    [RNBranch application:app openURL:url options:options]
    return YES;
}

- (BOOL)application:(UIApplication *)application continueUserActivity:(NSUserActivity *)userActivity restorationHandler:(void (^)(NSArray<id<UIUserActivityRestoring>> * _Nullable))restorationHandler {
   [RNBranch continueUserActivity:userActivity];
   return YES;
}

@end

Android

  • Add Branch to your MainApplication.java
// import from RNBranch
import io.branch.rnbranch.RNBranchModule;

public class MainApplication extends Application implements ReactApplication {

// add onCreate() override
@Override
public void onCreate() {
  super.onCreate();
  
  // Branch logging for debugging
  RNBranchModule.enableLogging();
  
  RNBranchModule.getAutoInstance(this);
}
// imports from RNBranch
import io.branch.rnbranch.RNBranchModule;
import io.branch.rnbranch.RNBranchPackage;

public class MainApplication extends Application implements ReactApplication {
 
// add RNBranchPackage to react-native package list
@Override
  protected List<ReactPackage> getPackages() {
    return Arrays.<ReactPackage>asList(
            new MainReactPackage(),
            new RNBranchPackage(),

// add onCreate() override
@Override
public void onCreate() {
  super.onCreate();
  
  // Branch logging for debugging
  RNBranchModule.enableLogging();
  
  RNBranchModule.getAutoInstance(this);
}
  • Add Branch to your MainActivity.java
import io.branch.rnbranch.*;
import android.content.Intent;

public class MainActivity extends ReactActivity {

      @Override
      protected String getMainComponentName() {
          return "base";
      }

      // Override onStart:
      @Override
      protected void onStart() {
          super.onStart();
          RNBranchModule.initSession(getIntent().getData(), this);
      }
            
      // Override onNewIntent:
      @Override
      public void onNewIntent(Intent intent) {
          super.onNewIntent(intent);
          RNBranchModule.onNewIntent(intent);
      }

}

Implement Features

Import Branch

  • In any React Native source file that uses the Branch SDK.
import branch from 'react-native-branch'
Class Declaration
BranchParams L14
BranchEventParams L34
BranchEvent L54
BranchUnsubscribe L215
BranchSubscribe L216
BranchUniversalObjectOptions L220
BranchShareSheetOptions L253
BranchLinkProperties L261
BranchLinkControlParams L270
BranchUniversalObject L279
Branch L294

Create content reference

let buo = await branch.createBranchUniversalObject('content/12345', {
  title: 'My Content Title',
  contentDescription: 'My Content Description',
  contentMetadata: {
    customMetadata: {
      key1: 'value1'
    }
  }
})

Create deep link

let linkProperties = {
  feature: 'sharing',
  channel: 'facebook',
  campaign: 'content 123 launch'  
}

let controlParams = {
  $desktop_url: 'https://example.com/home',
  custom: 'data'   
}

let {url} = await buo.generateShortUrl(linkProperties, controlParams)

Share deep link

let shareOptions = { 
  messageHeader: 'Check this out', 
  messageBody: 'No really, check this out!' 
}

let linkProperties = {
  feature: 'sharing', 
  channel: 'facebook' 
}

let controlParams = { 
  $desktop_url: 'http://example.com/home', 
  $ios_url: 'http://example.com/ios' 
}

let {channel, completed, error} = await buo.showShareSheet(shareOptions, linkProperties, controlParams)

Read deep link

  • Retrieve Branch data from a deep link

  • Best practice to receive data from the listener (to prevent a race condition)

  • Returns deep link properties

// listener
branch.subscribe(({error, params, uri}) => {
  if (error) {
    console.error('Error from Branch: ' + error)
    return
  }
  // params will never be null if error is null
})

let lastParams = await branch.getLatestReferringParams() // params from last open
let installParams = await branch.getFirstReferringParams() // params from original install

NativeLink™ Deferred Deep Linking

  • Use iOS pasteboard to enable deferred deep linking via Branch NativeLink™

🚧

Prerequisite

Minimum SDK version: v5.0.4

or

Options for Implementation

  • Enable in the AppDelegate by calling [RNBranch.branch checkPasteboardOnInstall]; before the Branch initialization in didFinishLaunchingWithOptions
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // enable pasteboard check
    [RNBranch.branch checkPasteboardOnInstall]; 
    [RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES];

    return YES;
}
  • Enable in the AppDelegate for iOS 15+ Only
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // enable pasteboard check for iOS 15+ only
    if ([[[UIDevice currentDevice] systemVersion] compare:@"15.0" options:NSNumericSearch] != NSOrderedAscending)
        [RNBranch.branch checkPasteboardOnInstall]; 

    [RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES];
    
    return YES;
}
  • Enable in the AppDelegate with check notification
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
    // enable pasteboard check
    [RNBranch.branch checkPasteboardOnInstall];
  
    // check if pasteboard toast will show
    if ([RNBranch.branch willShowPasteboardToast]) {
        // developers can notify the user of what just occurred here if they choose
    }

    [RNBranch initSessionWithLaunchOptions:launchOptions isReferrable:YES];

    return YES;
}

Create QR Code

  • Create a BranchQRCodeSettings object

  • Create a BranchUniversalObject, BranchLinkProperties, and Link Control Params.

  • Use getBranchQRCode() to create a QR code.

var qrCodeSettings = {
    width: 500,
    codeColor: "#3b2016",
    backgroundColor: "#a8e689",
    centerLogo: "https://cdn.branch.io/branch-assets/159857dsads5682753-og_image.png",
    margin: 1,
    imageFormat: "PNG"
};

var buoOptions = {
    title: "A Test Title",
    contentDescription: "A test content desc",
    contentMetadata: {
        price: "200",
        productName: "QR Code Scanner",
        customMetadata: { "someKey": "someValue", "anotherKey": "anotherValue" }
    }
};

var lp = {
    feature: "qrCode",
    tags: ["test", "working"],
    channel: "facebook",
    campaign: "posters"
};

var controlParams = {
    $desktop_url: "https://www.desktop.com",
    $fallback_url: "https://www.fallback.com"
};

try {
    var result = await branch.getBranchQRCode(qrCodeSettings, buoOptions, lp, controlParams);
}
catch (err) {
    console.log('QR Code Err: ', err);
}

Enable 100% Matching

Android

  • Uses Chrome Tabs to increase attribute matching success
  • Add implementation com.android.support:customtabs:28.0.0 to your build.gradle
  • If you need the custom tabs library but do not wish to enable 100% matching you can call Branch.enableCookieBasedMatching(null) prior to session initialization.

Navigate to content

branch.subscribe(({error, params, uri}) => {
  if (error) {
    console.error('Error from Branch: ' + error)
    return
  }

  // params will never be null if error is null

  if (params['+non_branch_link']) {
    const nonBranchUrl = params['+non_branch_link']
    // Route non-Branch URL if appropriate.
    return
  }

  if (!params['+clicked_branch_link']) {
        // A Branch link opened.
      // Route link based on data in params
      this.navigator.push({params: params, uri: uri})
    return
  }
})

Adjust cached link TTL

  • Any link that launched the app is cached by the native layers and returned to the branch.subscribe listener after JavaScript finishes loading.

  • By default, the initial link is cached for 5 seconds. This allows you to unsubscribe and resubscribe later without receiving the initial link.

  • If your app takes longer than this to load, you can adjust the TTL for the initial link by adjusting branch.initSessionTtl to a value in milliseconds.

branch.initSessionTtl = 10000 // Set to 10 seconds
branch.subscribe({ error, params } => {
  // ...
})

Track users

  • Sets the identity of a user (ID, UUID, etc) for events, deep links, and referrals

  • Validate with the Branch Dashboard

branch.setIdentity('theUserId')
branch.logout()

Track events

By default, the Branch SDK tracks clicks, opens, installs, reinstalls and impressions automatically (out-of-the-box).

Please refer to our Event Tracking Docs for more information and examples:

Handle links in your own app

  • Allows you to deep link into your own from your app itself
branch.openURL("https://example.app.link/u3fzDwyyjF")
branch.openURL("https://example.app.link/u3fzDwyyjF", {newActivity: true}) // Finish the Android current activity before opening the link. Results in a new activity window. Ignored on iOS.

❗️

Handling a new deep link

Handling a new deep link in your app will clear the current session data and a new referred "open" will be attributed.

Handle push notifications

Allows you to track Branch deep links in your push notifications.

Please refer to our Native SDK Documentation:

Set initialization metadata

If you are using a 3rd Party Data Integration Partner that requires setting certain identifiers before initializing the Branch SDK, you should add this code snippet:

RNBranch.setRequestMetadataKey("{ANALYTICS_ID}", "…")
[[RNBranch getInstance] setRequestMetadataKey:@"{ANALYTICS_ID}" value: […]];
RNBranchModule.setRequestMetadata("{ANALYTICS_ID}", "…");

Receive notification before a link is opened

Requires react-native-branch 5.x

To be notified that Branch is about to open a link, use an onOpenStart callback with branch.subscribe. Also supply an onOpenComplete callback, which is the same as the single callback usually used with branch.subscribe:

import branch from 'react-native-branch';

branch.subscribe({
  onOpenStart: ({uri, cachedInitialEvent}) => {
    // cachedInitialEvent is true if the event was received by the
    // native layer before JS loaded.
    console.log('Branch will open ' + uri);
  },
  onOpenComplete: ({error, params,uri}) => {
    if (error) {
      console.error('Error from Branch opening uri ' + uri);
      return;
    }

    console.log('Branch opened ' + uri);
    // handle params
  },
})

Note that uri will be null in some cases, particularly in the case of a deferred deep link. In these cases, consult the params for ~referring_link, +url or +non_branch_link to determine the referring URI/URL.

Troubleshoot Issues

Please refer to out Native SDK Docs:

Using getLatestReferringParams to handle link opens

The getLatestReferringParams method is essentially a synchronous method that retrieves the latest referring link parameters stored by the native SDK. However, React Native does not support synchronous calls to native code from JavaScript, so the method returns a promise. You must await the response or use then to receive the result. The same remarks apply to the getFirstReferringParams method.

However, this is only a restriction of React Native. The purpose of getLatestReferringParams is to retrieve those parameters one time. The promise will only return one result. It will not continue to return results when links are opened or wait for a link to be opened. This method is not intended to notify the app when a link has been opened.

To receive notification whenever a link is opened, including at app launch, call
branch.subscribe. The callback to this method will return any initial link that launched the
app and all subsequent link opens. There is no need to call getLatestReferringParams at app launch to check for an initial link. Use branch.subscribe to handle all link opens.

Common build problems

  • Be sure to follow the instructions to Update from < 2.0.0 if your
    app used an earlier version of react-native-branch. In version 2.x, the native SDKs are embedded
    in the NPM module and must not also be added from elsewhere (Gradle, CocoaPods, etc.).

  • Note that when using the React pod in a native app, the name of the native SDK pod is Branch-SDK, not Branch, and it comes from node_modules, not the CocoaPods repo.

  • Starting with React Native 0.40, all external iOS headers in Objective-C must be imported as
    #import <PackageName/Header.h>. This applies to React Native headers as well as the <react-native-branch/RNBranch.h> header from this SDK.

  • If you upgraded from RN < 0.40 manually, without adjusting your Xcode project settings, you may
    still be importing headers with double quotes. This probably indicates a problem with your settings.

  • The react-native-git-upgrade tool from NPM may be used to update dependencies as well as project settings.

  • On Android, when using Proguard in release builds, depending on your build settings, it may be
    necessary to add one or both of these lines to your android/app/proguard-rules.pro file:

-dontwarn com.crashlytics.android.answers.shim.**
-dontwarn com.google.firebase.appindexing.**

General troubleshooting

See the troubleshooting guide for each native SDK:

Sample apps


Did this page help you?