This documentation is available as Markdown for AI agents and LLMs. See the full Markdown index or append .md to any documentation URL.
Shared routes
Edit page
Learn how to define shared routes or use arrays to use the same route multiple times with different layouts using Expo Router.
To match the same URL with different layouts, use groups with overlapping child routes. This pattern is very common in native apps. For example, in the X app, a profile can be viewed in every tab (such as home, search, and profile). However, there is only one URL that is required to access this route.
In the example below, src/app/_layout.tsx is the tab bar and each route has its own header. The src/app/(profile)/[user].tsx route is shared between each tab.
srcapp_layout.tsx(home)_layout.tsx[user].tsx(search)_layout.tsx[user].tsx(profile)_layout.tsx[user].tsxGroup segments are not part of the URL, so every shared route matches the same URL. Expo Router uses the group you are in to select between them. In-app navigation keeps the current group. A page reload, a bookmark, a shared URL, and a deep link are all cold links. A cold link has no current group, so Expo Router renders the first alphabetical match. The same URL can therefore render one screen after in-app navigation and a different screen after a page reload.
Shared routes can be navigated directly by including the group name in the route. For example, /(search)/baconbrix navigates to /baconbrix in the "search" layout. Use this form when a link must always open one specific group.
Do not use shared routes to give different user roles a different version of a screen. The URL does not carry the user's role, so a cold link cannot select the correct group, and protected routes do not change that. Declare the screen once and control access withStack.Protected.
Arrays
Array syntax is an advanced concept that is unique to native app development.
Instead of defining the same route multiple times with different layouts, use the array syntax (,) to duplicate the children of a group. For example, src/app/(home,search)/[user].tsx — creates src/app/(home)/[user].tsx and src/app/(search)/[user].tsx in memory.
To distinguish between the two routes use a layout's segment prop:
export default function DynamicLayout({ segment }) { if (segment === '(search)') { return <SearchStack />; } return <Stack />; }
To enable the array syntax, specify the initialRouteName for each group using unstable_settings object in the dynamic layout:
export const unstable_settings = { initialRouteName: 'home', search: { initialRouteName: 'search', }, }; export default function DynamicLayout({ segment }) { %%placeholder-start%% ... %%placeholder-end%% }
In the above example, the home route is the default route for the home group and the app. The search route is the default route for the search group.
Key points
- You can only provide groups for the current navigator.
- When using the array syntax, if there are two groups (for example,
(one)/(two)), only the last group's segment is used for matching the route. - If there are at least two group
initialRouteNames, but a defaultinitialRouteNameis not provided, the first group'sinitialRouteNameis used.