Skip to main content

Configuring links

In this guide, we will configure React Navigation to handle external links. This is necessary if you want to:

  1. Handle deep links in React Native apps on Android and iOS
  2. Enable URL integration in browser when using on web
  3. Use <Link /> or useLinkTo to navigate using paths.

Make sure that you have configured deep links in your app before proceeding. If you have an Android or iOS app, remember to specify the prefixes option.

The Navigation component accepts a linking prop that makes it easier to handle incoming links:

import { createStaticNavigation } from '@react-navigation/native';

const linking = {
enabled: 'auto' /* Automatically generate paths for all screens */,
prefixes: [
/* your linking prefixes */
],
};

function App() {
return (
<Navigation
linking={linking}
fallback={<Text>Loading...</Text>}
/>
);
}

const Navigation = createStaticNavigation(RootStack);

When you specify the linking prop, React Navigation will handle incoming links automatically. On Android and iOS, it'll use React Native's Linking module to handle incoming links, both when the app was opened with the link, and when new links are received when the app is open. On the Web, it'll use the History API to sync the URL with the browser.

You can also pass a fallback prop that controls what's displayed when React Navigation is trying to resolve the initial deep link URL.

tip

When passing a linking prop, define the linking object at the module-level or memoize it with useMemo so that React Navigation can cache the processed configuration.

Prefixes

The prefixes option can be used to specify custom schemes (e.g. example://) as well as host & domain names (e.g. https://example.com) if you have configured Universal Links or Android App Links.

For example:

const linking = {
prefixes: ['example://', 'https://example.com'],
};
note

The prefixes option has no effect on Web. The host & domain names will be automatically determined from the Website URL in the browser.

Multiple subdomains​

To match all subdomains of an associated domain, you can specify a wildcard by prefixing *. before the beginning of a specific domain. Note that an entry for *.example.com does not match example.com because of the period after the asterisk. To enable matching for both *.example.com and example.com, you need to provide a separate prefix entry for each.

const linking = {
prefixes: ['example://', 'https://example.com', 'https://*.example.com'],
};

Filtering certain paths

Sometimes we may not want to handle all incoming links. For example, we may want to filter out links meant for authentication (e.g. expo-auth-session) or other purposes instead of navigating to a specific screen.

To achieve this, you can use the filter option:

const linking = {
prefixes: ['example://', 'https://example.com'],
filter: (url) => !url.includes('+expo-auth-session'),
};

This is not supported on Web as we always need to handle the URL of the page.

Apps under subpaths

If your app is hosted under a subpath, you can specify the subpath at the top-level of the config. For example, if your app is hosted at https://example.com/app, you can specify the path as app:

const linking = {
prefixes: ['example://', 'https://example.com'],
config: {
path: 'app',

// ...
},
};

It's not possible to specify params here since this doesn't belong to a screen, e.g. app/:id won't work.

Mapping path to route names

If you specify enabled: 'auto' in the linking prop, React Navigation will automatically generate paths for all screens. For example, if you have a Profile screen in the navigator, it'll automatically generate a path for it as profile.

If you wish to handle the configuration manually, or want to override the generated path for a specific screen, you can specify linking property next to the screen in the navigator to map a path to a screen. For example:

const RootStack = createStackNavigator({
screens: {
Profile: {
screen: ProfileScreen,
linking: {
path: 'user',
},
},
Chat: {
screen: ChatScreen,
linking: {
path: 'feed/:sort',
},
},
},
});

In this example:

  • Chat screen that handles the URL /feed with the param sort (e.g. /feed/latest - the Chat screen will receive a param sort with the value latest).
  • Profile screen that handles the URL /user.

Similarly, when you have a nested navigator, you can specify the linking property for the screens in the navigator to handle the path for the nested screens:

const HomeTabs = createBottomTabNavigator({
screens: {
Home: {
screen: HomeScreen,
linking: {
path: 'home',
},
},
Settings: {
screen: SettingsScreen,
linking: {
path: 'settings',
},
},
},
});

const RootStack = createStackNavigator({
screens: {
HomeTabs: {
screen: HomeTabs,
},
Profile: {
screen: ProfileScreen,
linking: {
path: 'user',
},
},
Chat: {
screen: ChatScreen,
linking: {
path: 'feed/:sort',
},
},
},
});

In the above example, the following path formats are handled:

  • /home navigates to the HomeTabs -> Home screen
  • /settings navigates to the HomeTabs -> Settings screen
  • /user navigates to the Profile screen
  • /feed/:sort navigates to the Chat screen with the param sort

How does automatic path generation work?

When using automatic path generation with enabled: 'auto', the following rules are applied:

  • Screens with an explicit linking property are not used for path generation and will be added as-is.
  • Screen names will be converted from PascalCase to kebab-case to use as the path (e.g. NewsFeed -> news-feed).
  • Unless a screen has explicit empty path (path: '') to use for the homepage, the first leaf screen encountered will be used as the homepage.
  • Path generation only handles leaf screens, i.e. no path is generated for screens containing nested navigators. It's still possible to specify a path for them with an explicit linking property.

Let's say we have the following navigation structure:

const HomeTabs = createBottomTabNavigator({
screens: {
Home: {
screen: HomeScreen,
},
Settings: {
screen: SettingsScreen,
},
},
});

const RootStack = createStackNavigator({
screens: {
HomeTabs: {
screen: HomeTabs,
},
Profile: {
screen: ProfileScreen,
},
Chat: {
screen: ChatScreen,
},
},
});

With automatic path generation, the following paths will be generated:

  • / navigates to the HomeTabs -> Home screen
  • /settings navigates to the HomeTabs -> Settings screen
  • /profile navigates to the Profile screen
  • /chat navigates to the Chat screen

If the URL contains a query string, it'll be passed as params to the screen. For example, the URL /profile?user=jane will pass the user param to the Profile screen.

How it works

The linking works by translating the URL to a valid navigation state and vice versa using the configuration provided. For example, the path /rooms/chat?user=jane may be translated to a state object like this:

const state = {
routes: [
{
name: 'rooms',
state: {
routes: [
{
name: 'chat',
params: { user: 'jane' },
},
],
},
},
],
};

For example, you might want to parse the path /feed/latest to something like:

const state = {
routes: [
{
name