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
or _middleware
. 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:
One routes support the popular feature of nested layouts, via _layout.tsx
files, and parallel render-as-you-fetch data loading via export loader
.
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
If you are targeting web-only, you may use HTML elements:
app/index.tsx
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.
One uses brackets to match against a single dynamic parameter: ./blog/[slug].tsx
matches /blog/post-one
and /blog/post-two
:
One will match ./blog/[slug].tsx
to any /blog/*
route, and pass in the parameters to the route as follows:
Much like JavaScript supports rest parameters, One supports rest parameter routes which are defined using the [...rest].tsx
syntax.
In the case where a user navigates to /catalog/a/b/c
, the [...rest].tsx
route would receive a params prop as follows:
To have a custom 404 page, you can create a +not-found.tsx
route in any folder. It will act as the same as a [...rest].tsx
route in that it will catch all sub-routes for that folder.
Simply export a React component (default or named) from your not found page and it will render with a 404 status code.
You can choose a rendering strategy on a per-page basis using a filename suffix. For more on these modes, see the next documentation page, Routing Modes.
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.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:
You can define a group by naming a folder with surrounding parenthesis:
Groups are useful for a couple reasons:
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.
Edit this page on GitHub.