Диплинки требуют подписки Pro plan или выше.
Отложенные диплинки позволяют отследить, по какой ссылке пришёл пользователь, даже если у него не установлено ваше приложение.

Когда пользователь переходит по ссылке без установленного приложения, он перенаправляется в магазин приложений. После установки и открытия приложения вы можете получить информацию об исходной ссылке и перенаправить пользователя на соответствующий экран.
Android Play Store
Android предоставляет Install Referrer API , который позволяет получить информацию о том, как пользователь пришёл к установке вашего приложения, включая URL реферера.
Вот как это работает в двух словах:
- Пользователь нажимает на диплинк на устройстве без установленного приложения
- Revroute перенаправляет пользователя в App Store или Play Store с помощью таргетинга по устройствам
- Пользователь устанавливает приложение из магазина
- Приложение считывает реферер установки при первом запуске
- Приложение извлекает диплинк из URL реферера и отслеживает событие открытия диплинка через эндпоинт
/track/open - Перенаправление пользователя на соответствующий экран по целевому URL, возвращённому эндпоинтом
/track/open
Структура URL реферера
Когда Revroute перенаправляет пользователей в Play Store, URL реферера содержит информацию о диплинке во вложенной структуре. URL реферера выглядит так:
https://play.google.com/store/apps/details?id=com.example.app&referrer=deepLink%3Dhttps%253A%252F%252Fdub.sh%252FgpsЧтобы извлечь исходный диплинк, необходимо:
- Распарсить параметр
referrerиз URL Play Store - Декодировать URL для получения параметра
deepLink - Декодировать значение
deepLinkдля получения фактического диплинка
Примеры кода ниже показывают, как реализовать этот процесс извлечения.
Шаг 1: Добавьте зависимость Install Referrer
Сначала необходимо добавить библиотеку Google Play Install Referrer в ваш проект.
// package.json
{
"dependencies": {
"react-native-play-install-referrer": "latest"
}
}Шаг 2: Реализуйте логику Install Referrer
Теперь необходимо реализовать логику чтения реферера установки, извлечения диплинка и отслеживания открытия диплинка.
// InstallReferrerTracker.js
import { 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;Шаг 3: Инициализируйте трекер в приложении
Теперь необходимо инициализировать трекер Install Referrer при запуске приложения.
// App.js
import React, { useEffect } from 'react';
import InstallReferrerTracker from './InstallReferrerTracker';
const App = () => {
useEffect(() => {
const tracker = new InstallReferrerTracker();
// Track install referrer on app launch
tracker.trackInstallReferrer();
}, []);
return (
// Your app components
);
};
export default App;Шаг 4: Обработка навигации
Наконец, реализуйте логику навигации для перенаправления пользователей на соответствующий экран на основе целевого URL.
// InstallReferrerTracker.js (navigation method)
navigateToDestination(destinationUrl) {
// Parse the destination URL to determine which screen to navigate to
const url = new URL(destinationUrl);
const path = url.pathname;
// Example navigation logic
if (path.includes('/product/')) {
const productId = path.split('/product/')[1];
// Navigate to product detail screen
navigation.navigate('ProductDetail', { productId });
} else if (path.includes('/category/')) {
const categoryId = path.split('/category/')[1];
// Navigate to category screen
navigation.navigate('Category', { categoryId });
} else {
// Navigate to home screen
navigation.navigate('Home');
}
}Важные замечания
- Определение первого запуска: Реферер установки доступен только при первом запуске после установки. Убедитесь, что вы правильно отслеживаете это, чтобы избежать дублирования.
- Декодирование URL: URL реферера закодирован несколько раз. Убедитесь, что вы корректно декодируете его для извлечения исходного диплинка.
- Сетевые операции: Убедитесь, что все API-вызовы выполняются в фоновых потоках, чтобы не блокировать основной поток и обеспечить плавную работу приложения.
- Обработка ошибок: Всегда реализуйте корректную обработку ошибок для сетевых запросов и парсинга URL.
- Тестирование: Тщательно протестируйте реализацию с помощью внутреннего тестового трека Google Play Console.
Для начала мы рекомендуем использовать руководство быстрого старта для настройки диплинков в Revroute.
Связанные ресурсы
- Документация Google Play Install Referrer API
- Руководство по диплинкам Android
- Документация Revroute API
iOS App Store
В отличие от Android, iOS не предоставляет встроенного API реферера установки. Revroute реализует гибридный подход, сочетающий детерминистическое отслеживание (на основе буфера обмена) и вероятностное отслеживание (на основе IP), для обеспечения надёжных отложенных диплинков на iOS.
Как работают отложенные диплинки iOS в Revroute
Решение Revroute для отложенных диплинков iOS предоставляет два подхода к отслеживанию:
- Детерминистическое отслеживание на основе буфера обмена: Использует данные буфера обмена iOS для надёжной идентификации и открытия точного диплинка, с которым взаимодействовал пользователь.
- Вероятностное отслеживание на основе IP: Сопоставляет пользователей из веба в приложение на основе их IP-адреса.
Для детерминистического подхода, когда пользователь iOS без установленного приложения переходит по диплинку, Revroute перенаправляет его на пользовательскую посадочную страницу:

На этой странице отображаются два варианта:
- Get the App: Копирует диплинк в буфер обмена перед перенаправлением в App Store.
- Get the App without Copying: Перенаправляет напрямую в App Store без копирования диплинка в буфер обмена.
После установки приложения пользователем метод разрешения диплинка зависит от нажатой кнопки.
1. Детерминистическое отслеживание на основе буфера обмена
Этот метод использует буфер обмена iOS для передачи диплинка в приложение после установки, обеспечивая надёжное и прямое разрешение ссылки.
Вот как это работает в двух словах:
- Пользователь нажимает кнопку Get the App на посадочной странице.
- Revroute копирует URL диплинка в буфер обмена.
- Пользователь перенаправляется в App Store для скачивания приложения.
- После установки приложение считывает буфер обмена для получения диплинка.
- Приложение вызывает эндпоинт
/track/openс параметромdeepLinkв теле запроса напрямую или через поддерживаемый мобильный SDK Revroute. - Revroute возвращает целевой URL, и приложение направляет пользователя на соответствующий экран (подробнее см. быстрый старт диплинков).
2. Вероятностное отслеживание на основе IP
Этот метод основан на сопоставлении IP-адреса устройства пользователя из исходного события клика с событием открытия приложения после установки.
- Пользователь нажимает кнопку Get the App without Copying на посадочной странице.
- Пользователь перенаправляется напрямую в App Store для скачивания приложения.
- Revroute уже отследил клик и сохранил IP-адрес на момент клика по диплинку.
- После установки приложение вызывает эндпоинт
/track/openс параметромdubDomainв теле запроса напрямую или через поддерживаемый мобильный SDK Revroute. - Revroute сопоставляет пользователя по IP и возвращает целевой URL.
- Если целевой URL получен, приложение направляет пользователя на соответствующий экран (подробнее см. быстрый старт диплинков).
Отслеживание открытия диплинка
Следующая логика определяет, использовать ли отслеживание на основе буфера обмена или на основе IP:
- Отслеживание на основе буфера обмена: Используется, когда диплинк найден в буфере обмена (например,
acme.link). Приложение отправляет параметрdeepLinkв теле запроса. - Отслеживание на основе IP: Используется, когда диплинк не найден в буфере обмена или пользователь отклонил разрешение на вставку. Приложение отправляет только параметр
dubDomain, позволяя Revroute сопоставить пользователя по IP-адресу.
Это обеспечивает автоматический выбор наиболее надёжного метода отслеживания.
// App.js
import 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 endpoint
async 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);
}
}Обработка навигации
Получив URL диплинка из функции trackOpen, вы можете перенаправить пользователя на соответствующий экран.
// App.js with React Navigation
import React, { useEffect, useRef } from "react";
import { NavigationContainer } from "@react-navigation/native";
import { createNativeStackNavigator } from "@react-navigation/native-stack";
const Stack = createNativeStackNavigator();
export default function App() {
const navigationRef = useRef();
useEffect(() => {
const handleDeepLink = async () => {
const destinationURL = await trackOpen();
if (destinationURL && navigationRef.current) {
// Parse URL and navigate
const url = new URL(destinationURL);
const path = url.pathname;
if (path.includes("/product/")) {
const productId = path.split("/product/")[1];
navigationRef.current.navigate("Product", { productId });
} else {
navigationRef.current.navigate("Home");
}
}
};
handleDeepLink();
}, []);
return (
<NavigationContainer ref={navigationRef}>
<Stack.Navigator initialRouteName="Home">
<Stack.Screen name="Home" component={HomeScreen} />
<Stack.Screen name="Product" component={ProductScreen} />
</Stack.Navigator>
</NavigationContainer>
);
}Важные замечания
- Ограничения отслеживания по IP: Отслеживание по IP зависит от сетевого IP устройства, что может быть менее надёжным в корпоративных сетях, VPN или общедоступном Wi-Fi.
- Сетевые операции: Убедитесь, что все API-вызовы выполняются в фоновых потоках, чтобы не блокировать основной поток и обеспечить плавную работу приложения.
- Обработка ошибок: Реализуйте корректную обработку ошибок для сетевых запросов и доступа к буферу обмена, чтобы приложение корректно работало при сбоях.
- Тестирование: Тщательно протестируйте с помощью TestFlight или внутренней сборки, чтобы подтвердить работу процесса как для отслеживания через буфер обмена, так и через IP.
- Требования App Store: Убедитесь, что ваше приложение соответствует требованиям Apple App Store относительно доступа к буферу обмена и конфиденциальности пользователей.