Set up your app
React Native and Expo
Set up DL2App deep links in a React Native or Expo app: the config plugin, configure, and one listener for direct and deferred links.
For React Native 0.74 or newer, with or without Expo (SDK 51 or newer). The native code is a plain React Native module, so a React Native app does not need Expo or Expo Modules. With Expo you need a development build: Expo Go does not work, because the SDK has native code and your app needs its own associated domains.
Install (Expo)
npx expo install @dl2app/react-native{
"expo": {
"plugins": [
["@dl2app/react-native", { "subdomain": "myapp", "domains": ["go.myapp.com"] }]
]
}
}The plugin adds the associated domains on iOS and the verified intent filters on Android for myapp.dl2.app, myapp-alt.dl2.app and your custom domains. It keeps entries you already have. Rebuild the native app afterwards (npx expo prebuild --clean, or a new EAS build).
Install (React Native without Expo)
npm install @dl2app/react-native
cd ios && pod installAutolinking registers the native module on both platforms; there is nothing to add to MainApplication or the Podfile. Then:
- Add the hosts by hand as described for iOS (Associated Domains) and Android (the intent filter in the manifest).
- On iOS, pass incoming links to React Native. The React Native template does not do this for you.
- Rebuild the app. A Metro reload is not enough after adding native code.
import React
// Inside your AppDelegate class. Write "override func" if it subclasses RCTAppDelegate.
func application(_ app: UIApplication, open url: URL, options: [UIApplication.OpenURLOptionsKey: Any] = [:]) -> Bool {
return RCTLinkingManager.application(app, open: url, options: options)
}
func application(_ application: UIApplication, continue userActivity: NSUserActivity, restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void) -> Bool {
return RCTLinkingManager.application(application, continue: userActivity, restorationHandler: restorationHandler)
}Use
import DL2 from "@dl2app/react-native";
// Once, as early as possible, outside any component.
DL2.configure({
publishableKey: "pk_live_xxx",
linkDomains: ["myapp.dl2.app", "myapp-alt.dl2.app", "go.myapp.com"],
});
// One listener for direct links and for the deferred link after an install.
const unsubscribe = DL2.onLink((event) => {
navigation.navigate(event.path, event.data);
});With Expo Router, also add app/+native-intent.ts so the router does not try to route the short link itself.
Also available
DL2.getInitialLink(): the link that opened the app, once the first-launch check has finished.DL2.track(name, { value, currency, props }): report an in-app event against the link that brought the user.DL2.createLink({ path, data }): make a share link from inside the app, if the project allows it.deferred.useClipboard: opt in to the iOS clipboard hand-off.
What the SDK does for you
- Delivers one event for all three cases: a link that cold-starts the app, a link while it is running, and a deferred link on first launch.
- Queues links that arrive before your listener is registered, so a cold-start link is never lost.
- Falls back to the URL’s own path and query if our API cannot be reached within 3 seconds, so the app still navigates.
- Never throws into your app: errors go to an
onErrorcallback. - Reads no advertising identifier. See Privacy and App Store disclosure.