[RFC] File system-based routing #1
Replies: 20 comments 55 replies
-
I've been eagerly awaiting expo/router, and so far it looks incredible. I'm curious if it's possible to fully configure reachable routes using files in the For example, instead of specifying screens and their options in a layout file, imagine a convention where route files exported a // (root).tsx
// Provides the layout of the descendant matched routes, which in this case renders children in a native stack
export default function Layout({ children }: LayoutProps) {
return (
<NativeStack>
{children}
</NativeStack>
);
}
// my-route.tsx
export default function MyRoute() {
return (
<Text>This is my route</Text>
);
}
// my-route specifies its own navigation options, rather than me having to specify them in the ancestor layout
// if I delete this file, the configuration goes along with it – no more jumping around the codebase to "register"/"unregister" reachable routes
export const NavigationOptions = {
title: 'My Route',
headerLeft: <MenuIcon />,
}; |
Beta Was this translation helpful? Give feedback.
-
So excited for this. @EvanBacon is crushing it 🔥🔥🔥 I'll comment by mentioning the one (and only) issue I've found to be hard to solve with file-based routing: infinite stack pushes within a given tab. This issue is detailed (and solved) at nandorojo/solito#110 with component-based stacks. OverviewIf you're using Twitter or Instagram, you'll notice that you can continually push screens on top of each other without jumping from one tab to the next. Click a tweet → the user → another tweet → another user, etc. In each instance, it stays within the same tab. Ideally, the URLs themselves for linking from one place to the next don't change. You're still just linking to The naive solution would be to create a separate link & duplicate screen for each tab: I wanted to toss this out there to see if people have any ideas. My best thinking (currently) is to do the following:
This solution isn't great since it basically loses all the benefits of Expo Router. But it's a starting point. Curious to get any thoughts. |
Beta Was this translation helpful? Give feedback.
-
Hey, just want to comment out that I love the work you're doing for react-native, together with the expo team and @nandorojo . You guys are one of the stronger forces into making react-native the premier implementation for mobile application. One thing I'd like to suggest is that instead of using both |
Beta Was this translation helpful? Give feedback.
-
My current experience is, it feels better if the layout for route A sits within route A's folder... for example, for the routes above, I have auth and non-auth it also aligns with the next.js layout RFC :) |
Beta Was this translation helpful? Give feedback.
-
It would be nice if, instead of just importing Something like this: import { Router } from "expo-router"
export function App() {
const [isAuthenticated, setIsAuthenticated] = useState<boolean | undefined>(undefined)
useEffect(() => {
// Do something here to check authentication
})
if (isAuthenticated === undefined) {
return <SplashScreen />
}
return <Router initialRoute={isAuthenticated ? "/home" : "/auth" } />
} |
Beta Was this translation helpful? Give feedback.
-
Is there a reason that the routes need to use parenthesis? If I make a file at This is maybe a minor nitpick, but the parentheses are very strange to me. When I read it in documentation, I assume it's a placeholder. I was trying to follow the quick start guide and got stuck for five minutes because I made two files:
I assumed the docs were telling me to name my stack and use that for the routes. |
Beta Was this translation helpful? Give feedback.
-
I've been doing some experiments integrating Expo with Remix and have an example monorepo running with Remix and an expo-router Expo app with component sharing between the two — https://github.com/mikeylemmon/remix-rnw/tree/monorepo-expo-router. Based on my experience so far, I posted this to a discussion on the remix repo, but I think at the moment it's probably more relevant for discussion here: remix-run/remix#1578 (reply in thread)
@EvanBacon is there any chance of getting some hooks into the API to be able to override the matchers? If you're amenable in theory and have an idea for how you'd like it to work then I'd be happy to attempt an implementation. Or do you have any other suggestions for how unified expo/remix fs-routing could be achieved? Regardless, thanks so much for your work on this, it's a massive upgrade to building Expo apps! |
Beta Was this translation helpful? Give feedback.
-
Author of vite-plugin-ssr here.
This essentially tightly locks Expo Router with Next.js. I wonder whether it's a deliberate choice to marry Expo Router with Next.js forever. Or is there a plan to make Expo Router work with other frameworks? If Expo Router wants to support other frameworks, then it should have a flexible core with a JS API that accepts a function route => root component. I.e. it's the framework which takes care of doing the routing while providing the routing information to Expo Router. That way, Expo Router can adapt to any framework. Thoughts? |
Beta Was this translation helpful? Give feedback.
-
Firstly congrats to expo team for bring that "expo router". I didn´t give a deep look in expo route doc, i don´t know if you already cover this. |
Beta Was this translation helpful? Give feedback.
-
Just finished recording a React Native Radio episode with you, @EvanBacon, about this, and I'm really loving what you're doing. I do want to open a further discussion about using the
This structure has been in place for many versions and our CLI tooling, documentation, and much more is built around it. I would like to try implementing Expo Router with Ignite, but this presents a fairly significant effort. Additionally, I have qualms about having everything (non-co-located) be in the root (such as If we could configure the root of Expo Router to be something like Thoughts & discussion welcome! |
Beta Was this translation helpful? Give feedback.
-
So excited for this @EvanBacon! I think Expo Router could really help speed up development and could be a great improvement over the currently available navigation frameworks. One major benefit I see of Expo Router is that it seems to really get "out of the way" and let's developers focus on writing their application code rather than spending time writing code specific to the navigation framework. On that premise, I'd like to suggest a change to the way Expo Router handles passing parameters between screens. In React Navigation, (and Expo Router), params are passed via a In the interest of "getting out of the way", I'd propose removing these extra layers and translating route params and path variables directly into React props. Things like the The way I see it, this approach would accomplish four things:
Example: import { useEffect } from "react";
import { View, Text } from "react-native";
+ export type HomeProps = {
+ post: Post
+ };
- export default function Home({ navigation, route }) {
+ export default function Home({ post }: HomeProps) {
useEffect(() => {
- if (route.params?.post) {
- // Post updated, do something with `route.params.post`
+ if (post)
+ // Post updated, do something with `post`
// For example, send the post to the server
}
- }, [route.params?.post]);
+ }, [post]);
return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
<Text>Home Screen</Text>
<Link
href={{
pathname: "details",
// /* 1. Navigate to the details route with query params */
query: { itemId: 86, otherParam: "anything you want here" },
}}
>
Go to Details
</Link>
</View>
);
} |
Beta Was this translation helpful? Give feedback.
-
I'm interested in discussing this more. After using Sveltekit and Next 13, I found that I've enjoyed using only folders to define routes. Additionally, I've been looking into generating Typing solutions for Expo Router and from the different approaches I've researched I think Sveltekit's (using multiple rootDirs and generated types) is the simplest to implement and maintain - but again relies on routes only being defined via folders. |
Beta Was this translation helpful? Give feedback.
-
As Type Safety becomes more popular, I think we need to consider what approach Expo will take to generate typings for routes. Currently there are not many solutions that provide typing for file based routing, so there is room to experiment. The most feature rich is Sveltekit which provides types from
We could adopt a similar method for Expo Router
I've also tested using Typescript plugins (which Next 13 is using), but lack of type-checking during |
Beta Was this translation helpful? Give feedback.
-
When first release? |
Beta Was this translation helpful? Give feedback.
-
I see rc1 just dropped. Any breaking changes from last 0.0.45? |
Beta Was this translation helpful? Give feedback.
-
Loving this! Have successfully been playing with it locally (thanks for the example projects). Facing difficulties with the project building in EAS. Seems related to editing the Project setup is a fresh expo managed workflow project. Haven't done anything other than follow the steps for adding expo/router, followed by the command
|
Beta Was this translation helpful? Give feedback.
-
I'm annoyed of this design, if you were using storybook to manage your component (a pure component library ), but the file-base system enforce you to put those components into /app root? why? the /app root in my opinion is a application layer to combine your component with your business logic, however, whenever you want to set a pure component into Stack.Screen, you have to move those components into app/ folder? otherwise you cannot address to correct path ??????? |
Beta Was this translation helpful? Give feedback.
-
I'm with @monochrome-yeh on this point. I think for a lot devs Can we please at least make this configurable? I'd like to move |
Beta Was this translation helpful? Give feedback.
-
@EvanBacon Great work on Expo Router. I am using Branch deeplink URL's. I configured the app but after clicking on branch Universal deeplink I get Unmatched route which is correct because deeplink is masked with random string and which is not a valid file component in route hierarchy. I am able to intercept the incoming URL to decode it and read the data, however I dont know how to stop Expo router from navigating itself and let app handle the routing manually based on data passed in branch URL. Appreciate your help |
Beta Was this translation helpful? Give feedback.
-
✅ Complete
Expo Router v1 is now available! The v2+ roadmap is available here.
RFC
The entire contents of this repo are up for discussion. We are releasing the beta early and in a very volatile state! Please do not depend on this library in your production apps yet!
The most important part of the API is the routes convention as this cannot easily change after it's been locked in.
Routes convention:
app
directory.index.js
which doesn't add any segment to the URL.Built-in layouts:
expo-router
wraps and re-exports React Navigation navigators which can be used in layout routes.If you have comments or concerns please leave them below and I'll try to answer whatever I can.
Beta Was this translation helpful? Give feedback.
All reactions