Урок 08

Deep Linking

Deep link — открытие приложения по ссылке. Например, myapp://profile/123 или https://myapp.com/profile/123.

Зачем нужно

  • Ссылки из email, SMS, соцсетей
  • Пуш-уведомления
  • Реклама
  • Шаринг контента

Настройка React Navigation

import * as Linking from 'expo-linking';

const prefix = Linking.createURL('/');

const linking = {
    prefixes: [prefix, 'myapp://', 'https://myapp.com'],
    config: {
        screens: {
            Home: '',
            Details: 'post/:id',
            Profile: 'user/:userId',
            Settings: 'settings',
        },
    },
};

<NavigationContainer linking={linking} fallback={<Text>Загрузка...</Text>}>
    <RootNavigator />
</NavigationContainer>

Теперь myapp://post/5 откроет экран Details с id = 5.

Динамические сегменты

config: {
    screens: {
        Details: 'post/:id',
        Comment: 'post/:postId/comment/:commentId',
    },
}

:id — параметр.

Вложенные навигаторы

config: {
    screens: {
        Tabs: {
            screens: {
                Feed: 'feed',
                Profile: 'profile/:userId',
            },
        },
        Modal: 'modal',
    },
}

myapp://profile/abc откроет Tabs → Profile с userId = abc.

Параметры query

config: {
    screens: {
        Search: 'search?q=:query',
    },
}

myapp://search?q=react → Search с query = 'react'.

Настройка схемы

В app.json:

{
    "expo": {
        "scheme": "myapp"
    }
}

Теперь myapp:// — твоя схема.

Universal Links (iOS) и App Links (Android)

Для https://myapp.com/profile/123:

iOS: файл apple-app-site-association на домене.

Android: файл assetlinks.json + настройка intentFilters в app.json.

Expo упрощает:

{
    "expo": {
        "ios": {
            "associatedDomains": ["applinks:myapp.com"]
        },
        "android": {
            "intentFilters": [
                {
                    "action": "VIEW",
                    "data": [{ "scheme": "https", "host": "myapp.com" }],
                    "autoVerify": true,
                    "category": ["BROWSABLE", "DEFAULT"]
                }
            ]
        }
    }
}

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

В терминале:

npx uri-scheme open "myapp://post/5" --ios
npx uri-scheme open "myapp://post/5" --android

useLinkingURL

Внутри приложения:

import * as Linking from 'expo-linking';

function Screen() {
    const url = Linking.useURL();

    useEffect(() => {
        if (url) console.log('открыто по ссылке:', url);
    }, [url]);
}

Открыть ссылку

Linking.openURL('https://example.com');
Linking.openURL('mailto:hello@example.com');
Linking.openURL('tel:+79001234567');

Когда не работает

  • Приложение не установлено — для myapp:// откроется ошибка
  • Universal Links решат это: если приложение не установлено, откроется сайт
  • На iOS при первом запуске Universal Links могут не сработать — пользователь должен открыть приложение вручную

Итоги

  • linking в NavigationContainer
  • prefixes — схемы
  • config.screens — соответствие URL и экранов
  • :param для динамических сегментов
  • Universal Links для https
  • Linking.openURL для внешних ссылок