@limelink/react-native
v1.0.1
Published
LimeLink deep linking SDK for React Native
Maintainers
Readme
@limelink/react-native
React Native bridge for LimeLink universal/app links and deferred deep links.
Requirements
- Install floor: React Native 0.81 with React 19.1+
- New Architecture through the legacy-module interoperability layer
- Hermes; Legacy Architecture and JSC are unsupported
- Android API 24+
- iOS 12+
- Community CLI or Expo Development Build
The package uses one Legacy Native Module transport as a New Architecture interoperability implementation and is not a direct TurboModule. RN 0.81.5 is the minimum verification target; RN 0.85 Community, RN 0.86 Expo Development Builds, and an RN 0.86.2 packed-tarball consumer provide current integration evidence. Expo Go and web are unsupported because this package contains native code.
Install
pnpm add @limelink/react-nativeAndroid Community CLI
Add the public Maven repository to android/settings.gradle:
dependencyResolutionManagement {
repositories {
google()
mavenCentral()
maven {
url = uri("https://hellovelop.github.io/limelink-aos-sdk-binary/repository")
content { includeGroup("org.limelink") }
}
}
}React Native projects that prefer project repositories also add the same repository to android/build.gradle:
allprojects {
repositories {
maven {
url = uri("https://hellovelop.github.io/limelink-aos-sdk-binary/repository")
content { includeGroup("org.limelink") }
}
}
}Ensure MainActivity.onNewIntent updates the Activity intent:
override fun onNewIntent(intent: Intent) {
super.onNewIntent(intent)
setIntent(intent)
}Expo Development Build
Add the package config plugin:
{
"expo": {
"plugins": ["@limelink/react-native"]
}
}Then create a Development Build. The plugin adds the public Android Maven repository and MainActivity intent update. No GitHub credentials are required.
Usage
import LimeLink from '@limelink/react-native';
const subscription = LimeLink.addLinkListener({
onDeeplinkReceived(result) {
console.log(result.deeplinkUrl, result.source, result.originalUrl);
},
onDeferredDeepLinkNotFound() {
console.log('No deferred deep link');
},
onDeeplinkError(error) {
console.error(error.code, error.message, error.platform);
},
});
LimeLink.initialize({
projectId: '550e8400-e29b-41d4-a716-446655440000',
loggingEnabled: __DEV__,
});On iOS, do not forward Linking.getInitialURL() or JavaScript URL events into LimeLink. Forward native lifecycle URLs directly from AppDelegate:
import LimeLinkReactNative
func application(
_ application: UIApplication,
continue userActivity: NSUserActivity,
restorationHandler: @escaping ([UIUserActivityRestoring]?) -> Void
) -> Bool {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL else { return false }
return LimeLink.handleIncomingLink(url)
}
func application(
_ app: UIApplication,
open url: URL,
options: [UIApplication.OpenURLOptionsKey: Any] = [:]
) -> Bool {
LimeLink.handleIncomingLink(url)
}Scene-based apps call the same method for cold and warm links:
func scene(
_ scene: UIScene,
willConnectTo session: UISceneSession,
options connectionOptions: UIScene.ConnectionOptions
) {
connectionOptions.userActivities
.filter { $0.activityType == NSUserActivityTypeBrowsingWeb }
.compactMap(\.webpageURL)
.forEach { _ = LimeLink.handleIncomingLink($0) }
connectionOptions.urlContexts.forEach { _ = LimeLink.handleIncomingLink($0.url) }
}
func scene(_ scene: UIScene, continue userActivity: NSUserActivity) {
guard userActivity.activityType == NSUserActivityTypeBrowsingWeb,
let url = userActivity.webpageURL else { return }
LimeLink.handleIncomingLink(url)
}
func scene(_ scene: UIScene, openURLContexts contexts: Set<UIOpenURLContext>) {
contexts.forEach { _ = LimeLink.handleIncomingLink($0.url) }
}The native iOS SDK owns pre-initialization buffering, five-second deduplication, and the capacity-10 success FIFO; the RN wrapper adds no queue. Android owns cold and warm App Link lifecycle handling; do not recreate and forward the initial URL as a new Intent.
Manual deferred checks return an explicit outcome:
const outcome = await LimeLink.handleDeferredDeepLink();
if (outcome.status === 'matched') {
console.log(outcome.result.deeplinkUrl);
} else if (outcome.status === 'failed') {
console.error(outcome.error);
}Manual checks also notify listeners. Choose either the Promise or listener as the navigation owner.
Native dependencies are pinned to Android org.limelink:limelink-aos-sdk:1.0.1 and binary CocoaPod LimelinkIOSSDK 1.0.1. Deferred deep links are supported automatically and do not require an initialization flag.
Native SDK 1.0.1 uses one result contract for direct, Universal/App, and deferred links. An unresolved Universal/App Link is delivered as a successful callback with deeplinkUrl: null, the exact inbound URL in originalUrl, source: 'universalLink', and isDeferred: false; it does not emit a separate error callback.
