Branch Metrics React Native SDK
react-native-branch is the official React Native SDK for Branch Metrics, a comprehensive mobile linking and attribution platform. It enables developers to integrate deep linking, deferred deep linking, mobile attribution, and analytics into their React Native applications, supporting both iOS and Android platforms. The current stable version is 6.9.0, with frequent updates (typically monthly or bi-monthly) to align with native Branch SDK releases and to expose new methods for compliance and functionality. Key differentiators include its robust deep linking capabilities across platforms, detailed attribution analytics for marketing campaigns, and features like Universal Links and App Links for seamless user experiences. It abstracts much of the underlying native SDK complexity, providing a unified JavaScript interface.
Common errors
-
Error: The navigation state parsed from the URL contains routes not present in the root navigator. This usually means that the linking configuration doesn't match the navigation structure.
cause This error typically occurs when React Navigation's deep linking configuration doesn't correctly map the incoming Branch deep link parameters (e.g., `screen` or `path`) to an existing route in your app's navigation stack.fixVerify that your `linking` configuration in `React Navigation` (e.g., in your root navigator) accurately defines the paths and screens that correspond to the data you expect from Branch deep links. Use `branch.subscribe` to get params and debug the expected navigation structure. -
ld: 1 duplicate symbol for architecture arm64
cause Often indicates that the native Branch SDK is included multiple times in your iOS project, for example, once by `react-native-branch` and again manually via CocoaPods or direct framework embedding.fixIf using `react-native-branch` version 2.0.0 or newer, remove any manual `pod 'Branch-SDK'` or `pod 'Branch'` entries from your `Podfile`. The React Native module handles native SDK inclusion automatically. Run `pod install --repo-update` after modifying your Podfile. -
Manifest merger failed : uses-sdk:minSdkVersion 16 cannot be smaller than version 19 declared in library [:react-native-branch] AndroidManifest.xml
cause Your app's `minSdkVersion` in `android/app/build.gradle` is lower than the minimum required by `react-native-branch` (or its embedded native Android SDK).fixIncrease your project's `minSdkVersion` in `android/app/build.gradle` to match or exceed the requirement of `react-native-branch`. For modern React Native apps, a `minSdkVersion` of 21 or higher is generally recommended. Update to `minSdkVersion = 21` (or higher) in `defaultConfig` block. -
Type 'typeof import("/path/to/node_modules/react-native-branch/index")' has no default export.cause You are attempting to import `branch` as a default export, but the module might be configured to use named exports for the primary object, or you are using an older version where the import pattern was different.fixTry importing `branch` as a named export: `import { branch } from 'react-native-branch';`. If that doesn't work, refer to the specific version's documentation or use `import * as branch from 'react-native-branch';` for older CJS-like modules. The current official documentation implies `import branch from 'react-native-branch'` is correct.
Warnings
- breaking Major version updates of `react-native-branch` often involve significant updates to the underlying native iOS and Android SDKs. These can introduce breaking changes requiring manual updates to native project files (e.g., `Info.plist`, `AndroidManifest.xml`, `AppDelegate.mm`/`.swift`, `MainApplication.java`/`.kt`, `Podfile`). Always consult the official Branch SDK documentation and migration guides for each major release.
- gotcha Deep links failing to open the app or navigate correctly, especially from a killed state on iOS or Android, is a very common issue. This often stems from incorrect or incomplete native configuration for Universal Links (iOS) or App Links (Android).
- breaking The `setDebug()` method was removed in version 6.1.0. Debugging is now handled differently.
- gotcha Expo managed workflow projects have limitations with `react-native-branch` due to the need for custom native module configuration and early lifecycle method access. Direct integration is often problematic.
- deprecated Older versions (prior to v2.0.0) of `react-native-branch` might have required manual addition of native Branch SDKs via Gradle or CocoaPods. This is no longer necessary and can cause build conflicts.
Install
-
npm install react-native-branch -
yarn add react-native-branch -
pnpm add react-native-branch
Imports
- branch
const branch = require('react-native-branch');import branch from 'react-native-branch';
- BranchUniversalObject
import BranchUniversalObject from 'react-native-branch';
import { BranchUniversalObject } from 'react-native-branch'; - BranchEvent
import BranchEvent from 'react-native-branch';
import { BranchEvent } from 'react-native-branch';
Quickstart
import React, { useEffect, useState } from 'react';
import { Text, View, StyleSheet, Alert, Linking } from 'react-native';
import branch, { BranchUniversalObject, BranchEvent } from 'react-native-branch';
const HomeScreen = () => {
const [latestParams, setLatestParams] = useState(null);
useEffect(() => {
// Branch initialization and deep link subscription
const unsubscribe = branch.subscribe(({ error, params, uri }) => {
if (error) {
console.error('Error from Branch: ' + error);
return;
}
console.log('Branch Params:', params);
console.log('Branch URI:', uri);
setLatestParams(params);
if (params['+non_branch_link']) {
const nonBranchUrl = params['+non_branch_link'];
Alert.alert('Non-Branch Link', `Opened non-Branch URL: ${nonBranchUrl}`);
Linking.openURL(nonBranchUrl);
return;
}
if (params['+clicked_branch_link']) {
Alert.alert('Branch Link Opened', `Data: ${JSON.stringify(params, null, 2)}`);
// Handle routing based on params (e.g., params.screen, params.productId)
} else {
Alert.alert('App Opened', 'No Branch link clicked or initial session.');
}
});
// Example: Create a Branch Universal Object and generate a short URL
const createAndShareLink = async () => {
try {
let buo = await branch.createBranchUniversalObject('content/12345', {
locallyIndex: true,
title: 'My Awesome Product',
contentDescription: 'Check out this amazing product!',
contentMetadata: {
productId: '12345',
itemCategory: 'electronics',
customData: 'important_info',
},
});
let linkProperties = {
feature: 'share',
channel: 'app_share',
campaign: 'product_promo',
};
let controlParams = {
$desktop_url: 'https://example.com/product/12345',
$ios_url: 'https://apps.apple.com/app/id123456789',
$android_url: 'https://play.google.com/store/apps/details?id=com.yourapp',
};
let { url } = await buo.generateShortUrl(linkProperties, controlParams);
console.log('Generated Branch URL:', url);
// Example: Log a custom event
let event = new BranchEvent(BranchEvent.ViewItem, buo, {
transaction_id: 'trans_abc123',
currency: 'USD',
revenue: 10.00,
});
event.logEvent();
console.log('Logged custom event: ViewItem');
} catch (err) {
console.error('Error creating/logging Branch event or link:', err);
}
};
createAndShareLink();
return () => {
unsubscribe();
};
}, []);
return (
<View style={styles.container}>
<Text style={styles.title}>Branch SDK Example</Text>
{latestParams ? (
<View>
<Text style={styles.subtitle}>Latest Deep Link Params:</Text>
<Text style={styles.params}>{JSON.stringify(latestParams, null, 2)}</Text>
</View>
) : (
<Text>Waiting for deep link or initial app open...</Text>
)}
</View>
);
};
const styles = StyleSheet.create({
container: {
flex: 1,
justifyContent: 'center',
alignItems: 'center',
padding: 20,
backgroundColor: '#F5FCFF',
},
title: {
fontSize: 24,
fontWeight: 'bold',
marginBottom: 20,
},
subtitle: {
fontSize: 18,
fontWeight: '600',
marginTop: 10,
marginBottom: 5,
},
params: {
fontFamily: Platform.OS === 'ios' ? 'Courier' : 'monospace',
fontSize: 12,
backgroundColor: '#e0e0e0',
padding: 10,
borderRadius: 5,
},
});
export default HomeScreen;