HomeGuidesReferenceLearn
ArchiveExpo SnackDiscord and ForumsNewsletter

Create pages with Expo Router

Learn about the file-based routing convention used by Expo Router.


When a file is created in the app directory, it automatically becomes a route in the app. For example, the following files will create the following routes:

app
index.jsmatches '/'
home.jsmatches '/home'
[user].jsmatches dynamic paths like '/expo' or '/evanbacon'
settings
  index.jsmatches '/settings'

Pages

Pages are defined by exporting a React component as the default value from a file in the app directory. The file they are exported from must use one of the .js, .jsx, .tsx, .ts extensions.

For example, create the app directory in your project and then create a file index.js inside it. Then, add the following snippet:

Render text on any platform with the <Text> component from React Native.

app/index.js
import { Text } from 'react-native';

export default function Page() {
  return <Text>Home page</Text>;
}

Alternatively, you can write web-only React components such as <div>, <p>, and so on. However, these won't render on native platforms.

app/index.js
export default function Page() {
  return <p>Home page</p>;
}

The above example matches the / route in the app and the browser. Files named index match the parent directory and do not add a path segment. For example, app/settings/index.js matches /settings in the app.

Platform extensions (for example, .ios.js, .native.ts) are not supported in the app directory. See Platform-specific modules, for more information.

Dynamic routes

Dynamic routes match any unmatched path at a given segment level.

RouteMatched URL
app/blog/[slug].js/blog/123
app/blog/[...rest].js/blog/123/settings

Routes with higher specificity will be matched before a dynamic route. For example, /blog/bacon will match blog/bacon.js before blog/[id].js.

Multiple slugs can be matched in a single route by using the rest syntax (...). For example, app/blog/[...id].js matches /blog/123/settings.

Dynamic segments are accessible as search parameters in the page component.

app/blog/[slug].js
import { useLocalSearchParams } from 'expo-router';
import { Text } from 'react-native';

export default function Page() {
  const { slug } = useLocalSearchParams();

  return <Text>Blog post: {slug}</Text>;
}