Use this file to discover all available pages before exploring further.
Deep links require a Pro plan subscription or
higher.
Deferred deep linking allows you to track which link a user came from even when they don’t have your app installed.
When a user clicks a link without the app installed, they’re redirected to the app store. After installing and opening the app, you can retrieve the original link information and redirect them to the appropriate screen.
Android provides the Install Referrer API which allows you to retrieve information about how a user came to install your app, including the referrer URL.Here is how it works in a nutshell:
User taps a deep link on a device without your app installed
Dub redirects the user to the App Store or Play Store by using device targeting
User installs your app from the app store
App reads the install referrer on first launch
App extracts the deep link from the referrer URL and tracks the deep link open event using the /track/open endpoint
Redirect the user to the appropriate screen using the destination URL returned by the /track/open endpoint
When Dub redirects users to the Play Store, the referrer URL contains the deep link information in a nested structure. The referrer URL looks like this:
Now you’ll need to implement the logic to read the install referrer, extract the deep link, and track the deep link open.
// InstallReferrerTracker.jsimport { PlayInstallReferrer } from "react-native-play-install-referrer";class InstallReferrerTracker { constructor() { this.isFirstLaunch = true; } trackInstallReferrer() { // Check if this is the first launch if (!this.isFirstLaunch) { return; } PlayInstallReferrer.getInstallReferrerInfo((installReferrerInfo, error) => { if (!error) { console.log( "Install referrer = " + installReferrerInfo.installReferrer, ); if (installReferrerInfo.installReferrer) { // Extract the deep link from the referrer URL const deepLink = this.extractDeepLinkFromReferrer( installReferrerInfo.installReferrer, ); if (deepLink) { // Track the deep link open with the extracted URL this.trackDeepLinkOpen(deepLink); } } } else { console.log("Failed to get install referrer info!"); console.log("Response code: " + error.responseCode); console.log("Message: " + error.message); } this.isFirstLaunch = false; }); } extractDeepLinkFromReferrer(referrerUrl) { try { // Parse the referrer URL to extract the deep link // e.g. for referrer=deepLink%3Dhttps%253A%252F%252Fdub.sh%252Fgps // the deep link is https://dub.sh/gps const referrerUrlObj = new URL(referrerUrl); const deepLinkParam = referrerUrlObj.searchParams.get("deepLink"); return decodeURIComponent(deepLinkParam); return null; } catch (error) { console.error("Error extracting deep link from referrer:", error); return null; } } async trackDeepLinkOpen(deepLink) { try { const response = await fetch("https://api.dub.co/track/open", { method: "POST", headers: { "Content-Type": "application/json", }, body: JSON.stringify({ deepLink, }), }); if (response.ok) { const data = await response.json(); const destinationUrl = data.link.url; // Navigate to the destination URL in your app this.navigateToDestination(destinationUrl); } } catch (error) { console.error("Error tracking deep link open:", error); } } navigateToDestination(destinationUrl) { // Implement your navigation logic here // This will depend on your navigation library (React Navigation, etc.) console.log("Navigating to:", destinationUrl); }}export default InstallReferrerTracker;
First Launch Detection: The install referrer is only available on the first launch after installation. Make sure to track this properly to avoid duplicate tracking.
URL Decoding: The referrer URL is URL-encoded multiple times. Make sure to properly decode it to extract the original deep link.
Network Operations: Ensure that all API calls are made in background threads to avoid blocking the main thread and ensure smooth app performance.
Error Handling: Always implement proper error handling for network requests and URL parsing.
Testing: Test your implementation thoroughly using the Google Play Console’s internal testing track.
To get started, we recommend using the quickstart guide to set up your deep links on Dub.
Unlike Android, iOS doesn’t provide a built-in install referrer API. Dub implements a hybrid approach combining deterministic tracking (clipboard-based) and probabilistic tracking (IP-based) to ensure reliable deferred deep linking on iOS.
Dub’s iOS deferred deep linking solution provides two tracking approaches:
Deterministic clipboard-based tracking: Uses iOS clipboard data to reliably identify and open the exact deep link the user interacted with.
Probabilistic IP-based tracking: Matches users from the web to the app based on their IP address.
For the deterministic approach, when an iOS user who doesn’t have your app installed clicks on your deep link, Dub redirects them to a custom landing page:
This page displays two options:
Get the App: Copies the deep link to the clipboard before redirecting to the App Store.
Get the App without Copying: Redirects directly to the App Store without copying the deep link to the clipboard.
After the user installs your app, the deep link resolution method depends on the button they clicked.
This method uses the iOS clipboard to pass the deep link into your app after installation, ensuring reliable and direct link resolution.Here is how it works in a nutshell:
User taps Get the App button on the landing page.
Dub copies the deep link URL to the clipboard.
The user is redirected to the App Store to download your app.
After installation, your app reads the clipboard to retrieve the deep link.
Your app calls the /track/open endpoint with the deepLink parameter in the request body either directly or via a supported Dub Mobile SDK.
Dub returns the destination URL, and your app navigates the user to the appropriate screen (see deep links quickstart for more details).
This method relies on matching the user’s device IP address from the initial click event to the app open event after installation.
User taps Get the App without Copying button on the landing page.
The user is redirected directly to the App Store to download your app.
Dub has already tracked the click and stored the IP address at the time of deep link click.
After installation, your app calls the /track/open endpoint with the dubDomain parameter in the request body either directly or via a supported Dub Mobile SDK .
Dub matches the user using IP-based tracking and returns the destination URL.
If a destination URL is returned, your app navigates the user to the appropriate screen (see deep links quickstart for more details).
The following logic determines whether to use clipboard-based tracking or IP-based tracking:
Clipboard-based tracking: Used when a deep link is found in the clipboard (e.g., acme.link). The app sends the deepLink parameter in the request body.
IP-based tracking: Used when no deep link is found in the clipboard or the user declined paste permissions. The app sends only the dubDomain parameter, allowing Dub to match the user based on their IP address.
This ensures the most reliable tracking method is chosen automatically.
// App.jsimport React, { useEffect } from 'react';import Clipboard from '@react-native-clipboard/clipboard';import AsyncStorage from '@react-native-async-storage/async-storage';export default function App() { useEffect(() => { trackOpen(); }, []); return ( // Your app components );}// Make request to /track/open endpointasync function trackOpen() { try { // Check if this is first launch const hasLaunched = await AsyncStorage.getItem('app_first_launch'); if (hasLaunched !== null) { return; } await AsyncStorage.setItem('app_first_launch', 'false'); // Check clipboard for deep link const clipboard = await Clipboard.getString(); let requestBody; if (clipboard && clipboard.includes('acme.link')) { // Clipboard-based tracking requestBody = { deepLink: clipboard }; } else { // IP-based tracking fallback requestBody = { dubDomain: 'acme.link' }; } const response = await fetch('https://api.dub.co/track/open', { method: 'POST', headers: { 'Content-Type': 'application/json', }, body: JSON.stringify(requestBody), }); if (response.ok) { const data = await response.json(); const destinationURL = data.link?.url; if (destinationURL) { // Navigate to the destination URL console.log('Navigating to:', destinationURL); } } } catch (error) { console.error('Error tracking open:', error); }}
IP-based Tracking Limitations: IP-based tracking relies on the device’s network IP, which can be less reliable in environments like corporate networks, VPNs, or shared Wi-Fi.
Network Operations: Ensure that all API calls are made in background threads to avoid blocking the main thread and ensure smooth app performance.
Error Handling: Implement proper error handling for network requests, clipboard access to ensure the app behaves gracefully under failures.
Testing: Test thoroughly using TestFlight or an internal distribution build to confirm the flow works for both clipboard-based and IP-based tracking scenarios.
App Store Guidelines: Ensure your app complies with Apple’s App Store guidelines regarding clipboard access and user privacy.