Deep linking
Handle incoming deep links in your React Native app with the Grovs SDK.
Register onDeeplinkReceived once and route the user from its payload.
Listening for deep links
The listener gets the link that opened the app and its custom payload:
import Grovs from 'react-native-grovs-wrapper';
const listener = Grovs.onDeeplinkReceived((response) => {
console.log('Link:', response.link);
console.log('Data:', response.data);
// Route the user based on payload
if (response.data?.screen === 'product') {
navigation.navigate('Product', { id: response.data.productId });
}
});
// When you no longer need the listener
listener.remove();It fires for links that open the app, links delivered while it runs, deferred links matched after a fresh install (by fingerprint or clipboard), and tapped Grovs push campaigns (3.1). response.data holds the data passed when generating the link. The event also carries the link's tracking metadata on both platforms, though DeeplinkResponse doesn't type it.
From 3.1.0, response.link is optional: a push campaign without a link arrives with data only. Check link before using it.
When to register
Register once, in your root component or entry point. No race: the launch link is held natively and delivered when the first listener registers. iOS holds only the most recent link.
On Android each new registration restarts the native subscription and re-delivers the latest link to every listener. Registering in several components can navigate twice.
Links only arrive with the URL scheme, intent filters, Associated Domains, and AppDelegate and MainActivity forwarding from the Quick Start.
When the lookup fails
If the lookup fails (phone offline, backend unavailable), the native SDK keeps the link and retries after a widening wait, on return to foreground, and when the network comes back. The listener fires once it succeeds.
While the SDK is disabled
Links aren't resolved while setSDK(false) is in effect. On Android, setSDK(true) forwards onStart again, so a launch link is delivered then. On iOS it isn't replayed. See Privacy & Consent.
Clipboard-assisted deferred deep linking
When a copy-to-clipboard link opens in a browser, the preview page copies it to the clipboard before sending the visitor to the store. On first launch after install, if fingerprint matching found nothing, the native SDK reads the clipboard and attributes the install deterministically. The link arrives through onDeeplinkReceived, possibly several seconds after launch.
No JavaScript is needed. The check is skipped when the backend reports no recent clicks on your clipboard-enabled links. Only links on Grovs hosts or your configured domains are sent. Platform details (the iOS paste notice, the Android 12+ "pasted from your clipboard" toast) are on the iOS and Android pages.
If your links use a custom domain, list it. With the Expo config plugin, set clipboardDomains:
["react-native-grovs-wrapper", {
"apiKey": "your-api-key",
"scheme": "your_app_scheme",
"clipboardDomains": ["links.yourdomain.com"]
}]In a bare project, pass it to the native configure calls:
Grovs.configure(APIKey: "your-api-key", useTestEnvironment: false, autoTrackScreenViews: false, clipboardDomains: ["links.yourdomain.com"], enabled: GrovsWrapperSwift.isSDKEnabled(), delegate: GrovsWrapperSwift.shared)Grovs.configure(this, "your-api-key", useTestEnvironment = false, baseURL = null, autoTrackScreenViews = false, clipboardDomains = listOf("links.yourdomain.com"), enabled = GrovsConsent.isEnabled(this))Enable copy-to-clipboard per link with copyToClipboardIos and copyToClipboardAndroid, or set the project default in the dashboard. Flow, settings and limits: Copy to Clipboard.
Looking up a link
To read a link's details by path, use linkDetails (3.1).