Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat!: move layout route inside directory #89

Merged
merged 14 commits into from
Oct 18, 2022

Conversation

EvanBacon
Copy link
Contributor

@EvanBacon EvanBacon commented Oct 16, 2022

Motivation

Developers dogfooding the beta release of Expo Router at scale have mentioned wanting to try a different format for defining Layout Routes. This new format would involve putting the Layout Route in the layout directory and giving it a magic filename (_layout.js). This format would replace the existing format of using a sibling file with the same name as the layout folder (Remix-styled).

Implementation

In this PR I've added the ability to define a Layout Route as a file named _layout inside the layout folder.

Projects will need to migrate app-wide:

app
- (stack).js
  (stack)/
+   _layout.js
    index.js
  • The root navigator has been changed from Stack to a Layout unless specified otherwise in a Layout Route at app/_layout.js.

Considerations

Naming

The purpose of this change is to make the layout easier to find in larger codebases, for this reason, it makes sense to prefix the file with an underscore (e.g. _layout, _document, etc.) so the file floats to the top of the list. The problem with this is that now projects basically can never have a route named _layout in their app unless they added a custom rewrite. Using _ in URLs is often considered reserved for API routes, middleware, and other dev tools.

Another issue with using a set name like _layout is that developers must know about this magic name ahead of time. Previously you could name any file using any name you wanted, there were no magic names, reserved routes, or chances of typos causing confusing issues.

Projects also have the ability to create conflicting routes: foo.js and foo/index.js. Makings projects a bit easier to break. We currently assert in this case, but it's suboptimal.

This format also makes Expo Router a little less like Remix and still fairly different from Next.js, meaning it's a bit less optimal for developers switching between projects.

One benefit of this new approach is the ability to control the top-most navigator. By creating an app/_layout.js developers can control how all top-level routes are presented. This introduces the ability to break default 404 handling and the sitemap, but it also makes it a bit lighter as you could reuse the root navigator without having to create a second root layout.

Alternatively, we could consider using an extension like .layout.js which would enable the developer to change the file name if needed. The default would be index.layout.js or related.

At a glance

Before

Screen Shot 2022-10-16 at 2 49 01 PM

After

Screen Shot 2022-10-16 at 2 47 48 PM

Jump to File

When pressing ⌘P in VS Code and searching "feed" when the project has a Layout Route named feed and an Index Route (/feed).

Before

Previously, the layout route would be recommended first.

Screen Shot 2022-10-16 at 2 51 19 PM

Selecting this would take you to a file like:

import { Tabs } from 'expo-router/tabs';
export default Tabs;

Index Routes are nominally more difficult to find because multiple files can be named index. This will often net to be less than _layout, and developers are more used to the index format. The entire React stack (including React Native) have special handling for index filenames as well.

Screen Shot 2022-10-16 at 3 03 13 PM

After

The proposed format makes VS Code recommend the Index Route before the Layout Route.

Screen Shot 2022-10-16 at 2 51 05 PM

Selecting this would take you to a file like:

import { Text } from 'react-native';
export default function Page() {
  return <Text>My Feed</Text>
}

This also means the Layout Route is substantially harder to get to. Devs will need to type the name of the route + _layout like "feed/_layout". There is no special handling for files named _layout, meaning tooling will often strip the entire file path and just show _layout.js: error ....

Screen Shot 2022-10-16 at 3 01 27 PM

@nandorojo
Copy link

I personally prefer this over the previous API of file-to-folder siblings.

@EvanBacon EvanBacon marked this pull request as ready for review October 18, 2022 02:06
@EvanBacon EvanBacon merged commit eb2ae0a into main Oct 18, 2022
@EvanBacon EvanBacon deleted the @evanbacon/new-layout-format branch October 18, 2022 02:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants