You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: versioned_docs/version-8.x/configuring-links.md
+83Lines changed: 83 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -274,6 +274,7 @@ When using automatic path generation with `enabled: 'auto'`, the following rules
274
274
- Screen names will be converted from `PascalCase` to `kebab-case` to use as the path (e.g. `NewsFeed` -> `news-feed`).
275
275
- Unless a screen has explicit empty path (`path: ''`) to use for the homepage, the first leaf screen encountered will be used as the homepage.
276
276
- 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.
277
+
- If the same screen is used in multiple nested navigators with the same path pattern, the path will be marked as [shared](#shared-paths) automatically. This is detected by comparing the screen component or navigator reference.
277
278
278
279
Let's say we have the following navigation structure:
279
280
@@ -1179,6 +1180,87 @@ const config = {
1179
1180
1180
1181
With `exact` property set to `true`, `Profile` will ignore the parent screen's `path` config and you'll be able to navigate to `Profile` using a URL like `users/cal`.
1181
1182
1183
+
## Shared paths
1184
+
1185
+
Sometimes the same screen is present in multiple nested navigators. For example, each tab can have its own stack, and each stack can contain a `Profile`screen. Inthis case, you may want `/profile/jane` to keep the current tab focused and open the `Profile`screenin that tab.
1186
+
1187
+
React Navigation supports thiswith shared paths:
1188
+
1189
+
<Tabs groupId="config" queryString="config">
1190
+
<TabItem value="static" label="Static" default>
1191
+
1192
+
When using static configuration with automatic path generation (default behavior), shared paths are detected automatically when the same screen component or navigator reference appears in multiple branches with the same full path pattern:
1193
+
1194
+
```js
1195
+
const Profile = createNativeStackScreen({
1196
+
screen: ProfileScreen,
1197
+
linking: 'profile/:id',
1198
+
});
1199
+
1200
+
const FeedStack = createNativeStackNavigator({
1201
+
screens: {
1202
+
Feed: FeedScreen,
1203
+
Profile,
1204
+
},
1205
+
});
1206
+
1207
+
const SearchStack = createNativeStackNavigator({
1208
+
screens: {
1209
+
Search: SearchScreen,
1210
+
Profile,
1211
+
},
1212
+
});
1213
+
```
1214
+
1215
+
You can also set `shared` explicitly, which can be useful if the screen component is different but you still want to share the path:
1216
+
1217
+
```js
1218
+
const Profile = createNativeStackScreen({
1219
+
screen: ProfileScreen,
1220
+
linking: {
1221
+
path: 'profile/:id',
1222
+
shared: true,
1223
+
},
1224
+
});
1225
+
```
1226
+
1227
+
</TabItem>
1228
+
<TabItem value="dynamic" label="Dynamic">
1229
+
1230
+
When using dynamic configuration, specify `shared: true`for every screen config that should accept the same path:
1231
+
1232
+
```js
1233
+
const config = {
1234
+
screens: {
1235
+
FeedTab: {
1236
+
screens: {
1237
+
Feed: '',
1238
+
Profile: {
1239
+
path: 'profile/:id',
1240
+
shared: true,
1241
+
},
1242
+
},
1243
+
},
1244
+
SearchTab: {
1245
+
screens: {
1246
+
Search: 'search',
1247
+
Profile: {
1248
+
path: 'profile/:id',
1249
+
shared: true,
1250
+
},
1251
+
},
1252
+
},
1253
+
},
1254
+
};
1255
+
```
1256
+
1257
+
</TabItem>
1258
+
</Tabs>
1259
+
1260
+
When a shared path matches more than one screen, React Navigation uses the current navigation state to choose the matching branch when possible to handle deep links.
1261
+
1262
+
The first matching path is also the canonical path used when generating URLs. If you use [`alias`](#alias-for-paths), you need to explicitly mark the alias itself as `shared: true` when desired.
1263
+
1182
1264
## Omitting a screen from path
1183
1265
1184
1266
Sometimes, you may not want to have the route name of a screenin the path. For example, let's say you have a `Home` screen and the following config. When the page is opened in the browser you'll get `/home` as the URL:
@@ -1506,6 +1588,7 @@ Each item in the `alias` array can be a string matching the syntax of the `path`
1506
1588
1507
1589
-`path` (required) - The path pattern to match.
1508
1590
-`exact`- Whether to match the path exactly. Defaults to `false`. See [Matching exact paths](#matching-exact-paths) for more details.
1591
+
-`shared`- Whether this alias can resolve to multiple routes. Defaults to `false`. See [Shared paths](#shared-paths) for more details.
1509
1592
-`parse`-Function to parse path segments into param values. See [Passing params](#passing-params) for more details.
Copy file name to clipboardExpand all lines: versioned_docs/version-8.x/nesting-navigators.md
+110Lines changed: 110 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -591,6 +591,116 @@ function RootStack() {
591
591
</TabItem>
592
592
</Tabs>
593
593
594
+
## Sharing the same screen in multiple navigators
595
+
596
+
A common pattern in mobile apps is to nest stack navigators inside each tab of a bottom tab navigator. Often, there can be some screens that exist in each stack.
597
+
598
+
Let's say you have a `FeedStack` tab and a `SearchStack` tab, and both of them can navigate to a `Profile` screen. You can add the `Profile` screen to both stacks, so that when you navigate to it from the `Feed` screen, the `FeedStack` tab stays selected and the tab bar remains visible. Pressing back from `Profile` will take you back to the previous screen in the same tab.
Each `Profile` screen belongs to the stack where it was opened. Calling `navigate('Profile', { id: 'jane' })` from inside `FeedStack` opens `Profile` in `FeedStack`, while the same call from inside `SearchStack` opens it in `SearchStack`.
701
+
702
+
For deep linking and browser URL integration, you can [configure the same path for both screens](configuring-links.md#shared-paths) so that the URL is the same regardless of which stack it was opened from.
703
+
594
704
## Best practices when nesting
595
705
596
706
We recommend keeping navigator nesting to a minimum. Try to achieve the behavior you want with as little nesting as possible.
### Multiple screens can now share the same path pattern for deep linking
1167
+
1168
+
In React Navigation 7, each screen needed to have a unique path pattern for deep linking.
1169
+
1170
+
React Navigation 8, we now supported shared paths, which allows multiple screens to share the same path pattern. This is useful for cases where the same screen appears in multiple nested navigators, but you want them to use a single URL. e.g. each tab contains its own stack with a `Profile` screen, while both copies still use a single URL such as `/profile/jane`.
1171
+
1172
+
When using static configuration, this is detected automatically. It can also be explicitly specified with `shared: true` when using dynamic configuration, or when automatic detection won't detect this in static configuration:
1173
+
1174
+
```js
1175
+
constconfig= {
1176
+
screens: {
1177
+
FeedTab: {
1178
+
screens: {
1179
+
Feed:'',
1180
+
Profile: {
1181
+
path:'profile/:id',
1182
+
shared:true,
1183
+
},
1184
+
},
1185
+
},
1186
+
SearchTab: {
1187
+
screens: {
1188
+
Search:'search',
1189
+
Profile: {
1190
+
path:'profile/:id',
1191
+
shared:true,
1192
+
},
1193
+
},
1194
+
},
1195
+
},
1196
+
};
1197
+
```
1198
+
1199
+
When handling deep links that have shared paths, React Navigation will try to automatically select the correct navigator based on the current navigation state.
1200
+
1201
+
See [Shared paths](configuring-links.md#shared-paths) for more details.
1202
+
1166
1203
### Navigators now accept a `router` prop
1167
1204
1168
1205
A router defines how the navigator updates its state based on navigation actions. Previously, custom routers could only be used by [creating a custom navigator](custom-navigators.md#extending-navigators).
0 commit comments