The app directory is where One handles universal file system routing. Every file you create in it will be turned into a route, except for files named _layout. One only supports file system routes at this time, but we have a discussion for those who want to help us figure out a configuration-based approach.
Here's an example:
_layout.tsx
Wraps all files in this directory and below
index.tsx
Matches "/"
blog.tsx
index.tsx
Matches "/blog"
[slug].tsx
Matches a single sub-path of "/blog", like "/blog/hello"
[...rest].tsx
Matches all sub-paths, like "/blog/hello/world"
One routes support the popular feature of nested layouts, via _layout.tsx files, and parallel render-as-you-fetch data loading via export loader.
Route Structure
All .tsx files in the app dir are used to match your routes, besides layouts. Each individual file is referred to as a "page" to disambiguate them from the term "route," which we use to refer to the actual URL state in a browser on web (or React Navigation state on native).
All pages must export a React component to be rendered. You can choose between two ways to export it: export default or plain export. If you don't default export, we look for the first export that is capitalized. The reason we support this is simple - the React Refresh library doesn't support hot reloading default exports. We're looking into modifying it to support them for route files, but until then you may want to simply use export to maintain a nice hot reloading experience.
A simple page that matches the / route and will render on native and web:
app/index.tsx
import{ Text }from'react-native'
exportdefaultfunctionHomePage(){
return(
<Text>Hello world</Text>
)
}
If you are targeting web-only, you may use HTML elements:
app/index.tsx
exportdefaultfunctionHomePage(){
return(
<div>Hello world</div>
)
}
All index files match against /, so app/index.tsx matches to your root / route. You can give your page a name as well, for example app/about.tsx will the /about route.
The segments of a route, for example /hello/world, are referred to as "route parameters" or just "params", where "hello" and "word" are each a single parameter. Pages can match against parameters dynamically in two ways: matching a single parameter, or matching all parameters below them.
Single Parameter Routes
One uses brackets to match against a single dynamic parameter: ./blog/[slug].tsx matches /blog/post-one and /blog/post-two:
blog.tsx
index.tsx
Matches "/blog"
[slug].tsx
Matches a single sub-path of "/blog", like "/blog/hello"
One will match ./blog/[slug].tsx to any /blog/* route, and pass in the parameters to the route as follows:
exportfunctionloader({ params }){
// params.slug will be a string matching the URL parameter
}
exportdefaultfunctionBlogPostPage({ params }){
// params.slug will be a string matching the URL parameter
}
Rest Parameter Routes
Much like JavaScript supports rest parameters, One supports rest parameter routes which are defined using the [...rest].tsx syntax.
catalog.tsx
index.tsx
Matches "/catalog"
[...rest].tsx
Matches all sub-paths of "/catalog", like "/catalog/a/b/c"
In the case where a user navigates to /catalog/a/b/c, the [...rest].tsx route would receive a params prop as follows:
route+ssg.tsx - Matches "/route", but will render the page as a SSG route.
route+spa.tsx - Matches "/route", but will render the page as a SPA route.
route+ssr.tsx - Matches "/route", but will render the page as a SSR route.
route+api.tsx - Matches "/route", but will render the page as an API route.
Routing per-platform
You can target a specific platform using the same specific extension convention as React Native - ie, using .web.tsx, .native.tsx, .ios.tsx, or .android.tsx as the last part of the filename.
This lets you diverge the routing based on the platform. For example:
index.tsx
Matches "/" on native"
index.web.tsx
Matches "/" on web
blog.web.tsx
Matches "/blog" on web, on native there will be no route
Groups
You can define a group by naming a folder with surrounding parenthesis:
_layout.tsx
(blog)
_layout.tsx
This layout will nest inside the above layout
blog.tsx
Matches "/blog"
[slug].tsx
Matches a single sub-path of "/blog", like "/blog/hello"
Groups are useful for a couple reasons:
They're useful to organize similar things without forcing you to nest URL segments.
They let you nest layouts, also without nesting segments.
Types
One generates types for your routes, so that you get type checking on a variety of things like the Link component.
The types are generated into your root directory, in a routes.d.ts file. You must make sure your tsconfig.json picks up this file.