SDKsReact Native
Deep Links
Handle deep links in React Native for cold and warm start.
Deep links arrive in two scenarios: cold start (app launched by a link) and warm start (app brought from background by a link). Handle both in your root component.
Basic Setup
import { useEffect } from 'react';
import { WarpLink } from '@warplink/react-native';
function App() {
useEffect(() => {
// Warm-start: app already running, new link arrives
const unsubscribe = WarpLink.onDeepLink((event) => {
if (event.deepLink) {
navigateTo(event.deepLink.destination);
} else if (event.error) {
console.error('Deep link error:', event.error.message);
}
});
// Cold-start: app launched by a link
WarpLink.getInitialDeepLink().then((link) => {
if (link) {
navigateTo(link.destination);
}
});
return unsubscribe; // Clean up listener on unmount
}, []);
return <>{/* Your app */}</>;
}With React Navigation
import { useEffect } from 'react';
import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
import { WarpLink } from '@warplink/react-native';
function App() {
const navigationRef = useNavigationContainerRef();
useEffect(() => {
const unsubscribe = WarpLink.onDeepLink((event) => {
if (event.deepLink) {
const url = event.deepLink.deepLinkUrl ?? event.deepLink.destination;
navigationRef.navigate('Product', { url });
}
});
WarpLink.getInitialDeepLink().then((link) => {
if (link) {
const url = link.deepLinkUrl ?? link.destination;
navigationRef.navigate('Product', { url });
}
});
return unsubscribe;
}, [navigationRef]);
return (
<NavigationContainer ref={navigationRef}>
{/* Your navigator */}
</NavigationContainer>
);
}Cold Start vs Warm Start
| Scenario | API | When |
|---|---|---|
| Cold start | getInitialDeepLink() | App was not running — launched by tapping a link |
| Warm start | onDeepLink(listener) | App was in background — brought to foreground by a link |
Both should be set up in the same useEffect to handle all cases.
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.