React Native

Configure Branch

Install Branch


Expo provides a File-based routing solution for iOS, Android, and web which automatically enables deep linking and query parameters for every page of your app. This makes Branch setup easier than ever!

The native Branch API is not available in the Expo Go app due to app store restrictions on tracking. To use Branch with Expo, you can create a custom development build with react-native-branch. The community Branch Config Plugin can be used to automatically configure react-native-branch with Expo Prebuild.

via Pure React Native App



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

  • Install the module

via Native iOS app with CocoaPods


platform :ios, '11.0'

target 'APP_NAME' do
  # if swift

  pod 'react-native-branch', path: '../node_modules/react-native-branch'
  • 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.

Configure App



Initialize Branch


  • In your app's AppDelegate file:
import RNBranch

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 isReferrable:YES];
    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;



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

public class MainApplication extends Application implements ReactApplication {

// add onCreate() override
public void onCreate() {
  // Branch logging for debugging
  • Add Branch to your
import io.branch.rnbranch.*;
import android.content.Intent;

public class MainActivity extends ReactActivity {

      protected String getMainComponentName() {
          return "base";

      // Override onStart:
      protected void onStart() {
          RNBranchModule.initSession(getIntent().getData(), this);
      // Override onNewIntent:
      public void onNewIntent(Intent 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: '',
  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: '', 
  $ios_url: '' 

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
    onOpenStart: ({
    }) => {
            'subscribe onOpenStart, will open ' +
            uri +
            ' cachedInitialEvent is ' +
    onOpenComplete: ({
    }) => {
        if (error) {
                'subscribe onOpenComplete, Error from opening uri: ' +
                uri +
                ' error: ' +
        if (params) {
            if (!params['+clicked_branch_link']) {
                if (params['+non_branch_link']) {
                    console.log('non_branch_link: ' + uri);
                    // Route based on non-Branch links
                // handle params
                let deepLinkPath = params.$deeplink_path as string; 
                let canonicalUrl = params.$canonical_url as string;
                // Route based on Branch link data 

let latestParams = 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™



Minimum SDK version: v5.0.4


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: "",
    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: "",
    $fallback_url: ""

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

Enable 100% Matching


  • Uses Chrome Tabs to increase attribute matching success
  • Add implementation 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.

Defer Initialization for Plugin Runtime

  • You may need to defer loading the native iOS/Android layer if you run into race conditions which cause apps to not receive Branch params on cold starts.
  • To do this, create a branch.json file which contains the following:
  "deferInitForPluginRuntime": true
  • On Android place this file in your src/main/assets folder
  • On iOS add this file through Xcode, File -> Add Files to "YourProject.xcodeproj" and add to Copy Bundle Resources for each target that inits the Branch SDK.

Adjust cached link TTL (Deprecated use Defer Initialization for Plugin Runtime)

  • 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

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("", {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:

Deep link to content from push notification by adding openURL to the callback function of the Push Notification handler

branch.openURL(data['branch'],{newActivity: true})

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:

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/ file:

General troubleshooting

See the troubleshooting guide for each native SDK:

Sample Applications