Deep Links
Handle deep links in your React Native app across iOS and Android, covering both cold start and warm start with the WarpLink SDK.
Deep links arrive in two scenarios: cold start (app launched by a link) and warm start (app brought from background by a link). The onLink callback you pass to configure() handles both. You do not need to wire up listeners in your components.
Basic Setup
Register onLink once at startup (see React Native SDK). Cold start, warm start, and deferred installs all flow through it:
import { WarpLink } from '@warplink/react-native';
WarpLink.configure({
apiKey: 'wl_live_yoursdkkeyhere000000000000000000',
onLink: ({ deepLink, error }) => {
if (error || !deepLink) return;
// Cold start, warm start, and deferred installs all arrive here.
navigateTo(deepLink.deepLinkUrl ?? deepLink.destination);
},
});
With React Navigation
Route to a screen from onLink using a navigation ref you set once:
import { createNavigationContainerRef } from '@react-navigation/native';
import { WarpLink } from '@warplink/react-native';
export const navigationRef = createNavigationContainerRef();
WarpLink.configure({
apiKey: 'wl_live_yoursdkkeyhere000000000000000000',
onLink: ({ deepLink, error }) => {
if (error || !deepLink) return;
if (navigationRef.isReady()) {
const url = deepLink.deepLinkUrl ?? deepLink.destination;
navigationRef.navigate('Product', { url });
}
},
});
Pass ref={navigationRef} to your NavigationContainer.
Cold Start vs Warm Start
| Scenario | Handled by | When |
|---|---|---|
| Cold start | onLink (automatic) | App was not running: launched by tapping a link |
| Warm start | onLink (automatic) | App was in background: brought to foreground by a link |
Both are delivered to onLink automatically. To drive them yourself, set automaticDeepLinks: false and use getInitialDeepLink() (cold start) and onDeepLink(listener) (warm start).
Manual Setup (Advanced)
With automaticDeepLinks: false, wire the listeners yourself in your root component:
import { useEffect } from 'react';
import { WarpLink } from '@warplink/react-native';
function App() {
useEffect(() => {
const unsubscribe = WarpLink.onDeepLink((event) => {
if (event.deepLink) navigateTo(event.deepLink.destination);
else if (event.error) console.error('Deep link error:', event.error.message);
});
WarpLink.getInitialDeepLink().then((link) => {
if (link) navigateTo(link.destination);
});
return unsubscribe;
}, []);
return <>{/* Your app */}</>;
}
Working with Deep Link Data
const link = await WarpLink.handleDeepLink('https://aplnk.to/abc123');
if (link) {
console.log('Link ID:', link.linkId);
console.log('Destination:', link.destination);
// Platform-specific deep link URL
if (link.deepLinkUrl) {
navigateToPath(link.deepLinkUrl);
}
// Custom parameters
const productId = link.customParams['product_id'] as string | undefined;
if (productId) {
showProduct(productId);
}
}
Error Handling
import { WarpLinkError, ErrorCodes } from '@warplink/react-native';
try {
const link = await WarpLink.handleDeepLink(url);
} catch (error) {
if (error instanceof WarpLinkError) {
switch (error.code) {
case ErrorCodes.E_NOT_CONFIGURED:
console.error('Call configure() first');
break;
case ErrorCodes.E_INVALID_URL:
console.error('Not a WarpLink URL');
break;
case ErrorCodes.E_LINK_NOT_FOUND:
showLinkExpired();
break;
case ErrorCodes.E_NETWORK_ERROR:
showOfflineMessage();
break;
default:
console.error(`[${error.code}] ${error.message}`);
}
}
}
Listener Events
The onDeepLink listener receives a discriminated union. Exactly one of deepLink or error is present:
WarpLink.onDeepLink((event) => {
if (event.deepLink) {
// Success — resolved deep link
console.log(event.deepLink.destination);
} else if (event.error) {
// Error — resolution failed
console.error(event.error.code, event.error.message);
}
});
Multiple listeners can be registered simultaneously. Each receives every event. The native event subscription is cleaned up when the last listener is removed.