Что такое deep linking и как его реализовать?

Deep linking — это механизм, позволяющий запускать мобильное приложение по специальной ссылке (URL) и направлять пользователя сразу на определённый экран внутри приложения. Это особенно полезно для навигации из e-mail, мессенджеров, push-уведомлений, баннеров и браузеров. В React Native реализация deep linking зависит от используемого навигационного решения (чаще всего это react-navigation) и требует настройки как на уровне JavaScript, так и на уровне нативных платформ — Android и iOS.

Типы deep linking

  1. Classic (Custom URL Scheme)
    Например: myapp://profile/123.
    Работает внутри приложений, браузеров и сообщений, но не везде надёжна на iOS (особенно если приложение не установлено).

  2. Universal Links (iOS)
    Например: https://myapp.com/profile/123.
    Работают и как обычные ссылки (если приложение не установлено — открываются в браузере), и как deep link (если установлено — открываются внутри приложения). Требует настройки домена и сервера.

  3. App Links (Android)
    Аналог Universal Links, работает с https:// и требует подтверждения владения доменом.

Конфигурация deep linking в React Native

1. Настройка react-navigation

npm install @react-navigation/native
npm install react-native-screens react-native-safe-area-context

Затем включаем поддержку ссылок:

import { NavigationContainer } from '@react-navigation/native';
const linking = {
prefixes: \['myapp://', 'https://myapp.com'\],
config: {
screens: {
Home: 'home',
Profile: 'profile/:id',
Settings: 'settings',
},
},
};
export default function App() {
return (
<NavigationContainer linking={linking}>
{/\* Навигация \*/}
</NavigationContainer>
);
}

Теперь URL myapp://profile/42 или https://myapp.com/profile/42 будет вести на экран Profile с параметром id = 42.

Работа с Linking API

React Native предоставляет модуль Linking, позволяющий работать с внешними ссылками:

import { Linking } from 'react-native';
useEffect(() => {
const handleDeepLink = (event) => {
const url = event.url;
console.log('Открыта ссылка:', url);
// можно вручную разобрать url и перенаправить
};
Linking.addEventListener('url', handleDeepLink);
Linking.getInitialURL().then((url) => {
if (url) {
handleDeepLink({ url });
}
});
return () => {
Linking.removeAllListeners('url');
};
}, \[\]);

Это полезно для кастомной обработки ссылок вне react-navigation.

Настройка Android

В android/app/src/main/AndroidManifest.xml:

Добавить <intent-filter> внутрь <activity>:

&lt;intent-filter android:autoVerify="true"&gt;
&lt;action android:name="android.intent.action.VIEW" /&gt;
&lt;category android:name="android.intent.category.DEFAULT" /&gt;
&lt;category android:name="android.intent.category.BROWSABLE" /&gt;
&lt;!-- Пример для кастомной схемы --&gt;
&lt;data android:scheme="myapp" /&gt;
&lt;!-- Пример для https-ссылок --&gt;
<data android:scheme="https"
android:host="myapp.com" />
&lt;/intent-filter&gt;

Если используешь App Links, нужно разместить файл assetlinks.json на сервере:

https://myapp.com/.well-known/assetlinks.json

Содержимое:

\[{
"relation": \["delegate_permission/common.handle_all_urls"\],
"target": {
"namespace": "android_app",
"package_name": "com.myapp",
"sha256_cert_fingerprints": \[
"F2:34:...:12"
\]
}
}\]

Настройка iOS

  1. В Info.plist добавить схему:
&lt;key&gt;CFBundleURLTypes&lt;/key&gt;
&lt;array&gt;
&lt;dict&gt;
&lt;key&gt;CFBundleURLSchemes&lt;/key&gt;
&lt;array&gt;
&lt;string&gt;myapp&lt;/string&gt;
&lt;/array&gt;
&lt;/dict&gt;
&lt;/array&gt;
  1. Для Universal Links:

  2. Включить Associated Domains в Xcode

  3. Добавить домен:

applinks:myapp.com

  • Разместить файл apple-app-site-association по адресу:

https://myapp.com/apple-app-site-association

Формат файла:

{
"applinks": {
"apps": \[\],
"details": \[{
"appID": "ABCDE12345.com.myapp",
"paths": \[ "/profile/\*", "/home", "/settings" \]
}\]
}
}

Тестирование

На Android можно протестировать, выполнив команду:

adb shell am start -W -a android.intent.action.VIEW -d "myapp://profile/123" com.myapp

На iOS:

  • Открыть Safari → ввести myapp://profile/123 → нажать "перейти"

  • Либо создать ярлык с открытием URL

Также можно открыть ссылку программно:

Linking.openURL('myapp://profile/123');

Expo: поддержка deep linking

Expo имеет встроенную поддержку. Конфигурация:

const linking = {
prefixes: \[Linking.createURL('/')\],
config: {
screens: {
Home: 'home',
Profile: 'profile/:id',
},
},
};

Expo автоматически регистрирует схему exp:// в отладке и myapp:// при eas build.

Чтобы протестировать в Expo Go:

Linking.openURL('exp://127.0.0.1:19000/--/profile/123');

Безопасность и ограничения

  • Убедись, что ссылки обрабатываются только внутри твоего приложения

  • Не допускай передачи чувствительных данных через ссылку (например, токены доступа)

  • Используй валидацию параметров перед навигацией

Полезные библиотеки

  • react-native-url-polyfill — для поддержки URL в старых RN-версиях

  • expo-linking — надстройка над Linking с поддержкой префиксов и парсинга

  • react-native-navigation — альтернативная библиотека, тоже поддерживает deep linking

Deep linking — мощный инструмент навигации, улучшающий UX, позволяющий запускать приложение снаружи, направлять на нужные экраны и передавать параметры. Его реализация требует согласованной настройки в JS, Android и iOS, но после этого он работает надёжно и гибко.