If you’re building a React Native app, intuitive navigation is crucial for a good user experience. Expo Router, part of the Expo SDK, offers a powerful solution for managing navigation in your app. In this post, we’ll explore the basics of Expo Router, a file-based router that simplifies screen navigation in React Native applications.
What is Expo Router?
Expo Router is a file-based router for React Native, built on top of React Navigation.
It abstracts much of the complex navigation code and setup, allowing you to manage routes using a file structure similar to modern web development frameworks like Next.js, Astro and Svelte.
With Expo Router, your file structure directly maps to your app’s routes. For example, a file at app/settings.tsx
would create a route accessible at /settings
in your app.
Key Concepts
To get started with Expo Router, let’s explore these five main concepts:
1. Folders & Pages
Folders and pages represent segments in the URL. Each file in the app
directory becomes a route in your application.
Example structure:
app/
index.tsx // maps to "/"
settings.tsx // maps to "/settings"
profile/
index.tsx // maps to "/profile"
details.tsx // maps to "/profile/details"
2. Home Page
The index.tsx
file is used as the home page for a route. At the root level, app/index.tsx
becomes your app’s main entry point.
3. Layout Routes
Layout routes, defined in _layout.tsx
files, determine how screens in a folder are laid out. They’re crucial for creating consistent UI across multiple screens.
The app/_layout.tsx
file serves as the root layout. It’s used to add providers that should be available to every route in the app, such as an AuthProvider.
Example app/_layout.tsx
:
import { Slot } from "expo-router";
export default function RootLayout() {
return (
<Provider>
<Slot /> {/* This renders the current child route */}
</Provider>
);
}
There can only be one layout route per directory. To use multiple layout routes, you would need to add multiple directories.
Example structure:
app
_layout.tsx
home
_layout.tsx
index.tsx
settings
_layout.tsx
index.tsx
about.tsx
4. Groups
Groups, which are represented using the ()
syntax, allow you to organize sections of your app without affecting the URL structure.
They’re useful for adding layouts or organizing code without introducing extra URL segments.
Example:
app/
(auth)/
login.tsx // maps to "/login"
register.tsx // maps to "/register"
(app)/
home.tsx // maps to "/home"
profile.tsx // maps to "/profile"
In Expo Router, the (tabs)
directory is a special type of group.
When you create a directory named (tabs)
, Expo Router knows to automatically use the Tabs layout for the screens inside that directory.
This is particularly useful for apps that rely on tab-based navigation, as it allows you to set up your tabs with minimal configuration.
5. Dynamic Routes
Dynamic routes, which are represented using square brackets []
, allow you to match any unmatched path at a given segment level.
Dynamic segments are accessible as route parameters in the page component.
Example app/user/[id].tsx
:
import { useLocalSearchParams } from "expo-router";
import { Text } from "react-native";
export default function UserProfile() {
const { id } = useLocalSearchParams();
return <Text>User Profile {id}</Text>;
}
This creates a route that matches any path like /user/123
or /user/abc
.
Common Questions
While learning Expo Router, I had several questions, which I’m sharing here, along with the answers I discovered, in hopes that they might help other developers who are new to Expo Router. Here are some of the key questions I encountered:
Do I always need a root index (app/index.tsx) file?
No, you don’t always need a root index file. For example, if your app has a tab-based navigation and no main entry screen like a login page, you can structure your app without an index file. However, having an index file at the root level is common for defining the initial route of your app.
Example:
app/
_layout.tsx
(tabs)/
_layout.tsx
index.tsx
settings.tsx
about.tsx
What’s the difference between /settings.tsx and /settings/index.tsx?
Both /settings.tsx
and /settings/index.tsx
map to /settings
in the URL. The main differences are:
- Use
/settings.tsx
for a standalone settings page. - Use
/settings/index.tsx
if you plan to nest other pages under the/settings
route, which can help keep your code organized.
For example, with /settings/index.tsx
, you could easily add /settings/profile.tsx
or /settings/notifications.tsx
as sub-pages.
How do I handle authentication with Expo Router?
You can use groups and layout routes for authentication. For example:
app/
_layout.tsx
login.tsx
(app)/
_layout.tsx <- Check authentication here
index.tsx
schedule.tsx
profile.tsx
In the (app)/_layout.tsx
, you can check for authentication and redirect to the login page if needed.
Example (app)/_layout.tsx
:
import { Redirect, Stack } from "expo-router";
import { useAuth } from "../../providers/AuthProvider";
export default function Layout() {
const { isAuthenticated } = useAuth();
if (!isAuthenticated) {
return <Redirect href="/login" />;
}
return <Stack />;
}
This blog post provides a high-level overview of Expo Router’s basic concepts, but it’s important to note that it’s not meant to be an exhaustive guide. Expo Router offers many more features and nuances that can enhance your React Native app’s navigation and structure.
For a more comprehensive understanding and advanced usage, I highly encourage you to explore the Expo Router documentation. The official docs provide excellent in-depth explanations, additional concepts, best practices, and up-to-date information on new features and updates.