|
| 1 | +# Routing |
| 2 | + |
| 3 | +The Epic Stack uses file-based routing with Remix. However, it's not using the |
| 4 | +built-in routing convention of Remix and instead is using |
| 5 | +[remix-flat-routes](https://github.com/kiliman/remix-flat-routes) which is a |
| 6 | +special implementation of the Remix convention that adds a few features. You'll |
| 7 | +find it configured for the application in the `remix.config.js` file at the root |
| 8 | +of the app. Specifically "hybrid routes." |
| 9 | + |
| 10 | +We'll defer to the `remix-flat-routes` documentation for specifics, but an |
| 11 | +important thing for you to know as you get used to this convention is you can |
| 12 | +always run `npx remix routes` from the root of the app and it will output the |
| 13 | +routes of your application in a JSX-like output that will reveal the routes that |
| 14 | +will be generated based on your current file structure. Here's an example of the |
| 15 | +Epic Stack routes at the time of this writing: |
| 16 | + |
| 17 | +``` |
| 18 | +app/routes |
| 19 | +├── _auth+ |
| 20 | +│ ├── forgot-password.tsx |
| 21 | +│ ├── login.tsx |
| 22 | +│ ├── logout.tsx |
| 23 | +│ ├── onboarding.tsx |
| 24 | +│ ├── reset-password.tsx |
| 25 | +│ └── signup.tsx |
| 26 | +├── _marketing+ |
| 27 | +│ ├── about.tsx |
| 28 | +│ ├── index.tsx |
| 29 | +│ ├── logos |
| 30 | +│ │ ├── logos.ts |
| 31 | +│ │ └── ... |
| 32 | +│ ├── privacy.tsx |
| 33 | +│ ├── support.tsx |
| 34 | +│ └── tos.tsx |
| 35 | +├── admin+ |
| 36 | +│ ├── cache.tsx |
| 37 | +│ ├── cache_.lru.$cacheKey.ts |
| 38 | +│ ├── cache_.sqlite.$cacheKey.ts |
| 39 | +│ └── cache_.sqlite.tsx |
| 40 | +├── me.tsx |
| 41 | +├── resources+ |
| 42 | +│ ├── delete-image.test.tsx |
| 43 | +│ ├── delete-image.tsx |
| 44 | +│ ├── delete-note.tsx |
| 45 | +│ ├── file.$fileId.tsx |
| 46 | +│ ├── healthcheck.tsx |
| 47 | +│ ├── image-upload.tsx |
| 48 | +│ ├── login.tsx |
| 49 | +│ ├── note-editor.tsx |
| 50 | +│ └── theme.tsx |
| 51 | +├── settings+ |
| 52 | +│ ├── profile.photo.tsx |
| 53 | +│ └── profile.tsx |
| 54 | +└── users+ |
| 55 | + ├── $username.tsx |
| 56 | + └── $username_+ |
| 57 | + ├── notes.$noteId.tsx |
| 58 | + ├── notes.$noteId_.edit.tsx |
| 59 | + ├── notes.index.tsx |
| 60 | + ├── notes.new.tsx |
| 61 | + └── notes.tsx |
| 62 | +
|
| 63 | +9 directories, 54 files |
| 64 | +``` |
| 65 | + |
| 66 | +```tsx |
| 67 | +<Routes> |
| 68 | + <Route file="root.tsx"> |
| 69 | + <Route path="forgot-password" file="routes/_auth+/forgot-password.tsx" /> |
| 70 | + <Route path="login" file="routes/_auth+/login.tsx" /> |
| 71 | + <Route path="logout" file="routes/_auth+/logout.tsx" /> |
| 72 | + <Route path="onboarding" file="routes/_auth+/onboarding.tsx" /> |
| 73 | + <Route path="reset-password" file="routes/_auth+/reset-password.tsx" /> |
| 74 | + <Route path="signup" file="routes/_auth+/signup.tsx" /> |
| 75 | + <Route path="about" file="routes/_marketing+/about.tsx" /> |
| 76 | + <Route index file="routes/_marketing+/index.tsx" /> |
| 77 | + <Route path="privacy" file="routes/_marketing+/privacy.tsx" /> |
| 78 | + <Route path="support" file="routes/_marketing+/support.tsx" /> |
| 79 | + <Route path="tos" file="routes/_marketing+/tos.tsx" /> |
| 80 | + <Route path="admin/cache" file="routes/admin+/cache.tsx" /> |
| 81 | + <Route |
| 82 | + path="admin/cache/lru/:cacheKey" |
| 83 | + file="routes/admin+/cache_.lru.$cacheKey.ts" |
| 84 | + /> |
| 85 | + <Route path="admin/cache/sqlite" file="routes/admin+/cache_.sqlite.tsx"> |
| 86 | + <Route path=":cacheKey" file="routes/admin+/cache_.sqlite.$cacheKey.ts" /> |
| 87 | + </Route> |
| 88 | + <Route path="me" file="routes/me.tsx" /> |
| 89 | + <Route |
| 90 | + path="resources/delete-image" |
| 91 | + file="routes/resources+/delete-image.tsx" |
| 92 | + /> |
| 93 | + <Route |
| 94 | + path="resources/delete-note" |
| 95 | + file="routes/resources+/delete-note.tsx" |
| 96 | + /> |
| 97 | + <Route |
| 98 | + path="resources/file/:fileId" |
| 99 | + file="routes/resources+/file.$fileId.tsx" |
| 100 | + /> |
| 101 | + <Route |
| 102 | + path="resources/healthcheck" |
| 103 | + file="routes/resources+/healthcheck.tsx" |
| 104 | + /> |
| 105 | + <Route |
| 106 | + path="resources/image-upload" |
| 107 | + file="routes/resources+/image-upload.tsx" |
| 108 | + /> |
| 109 | + <Route path="resources/login" file="routes/resources+/login.tsx" /> |
| 110 | + <Route |
| 111 | + path="resources/note-editor" |
| 112 | + file="routes/resources+/note-editor.tsx" |
| 113 | + /> |
| 114 | + <Route path="resources/theme" file="routes/resources+/theme.tsx" /> |
| 115 | + <Route path="settings/profile" file="routes/settings+/profile.tsx"> |
| 116 | + <Route path="photo" file="routes/settings+/profile.photo.tsx" /> |
| 117 | + </Route> |
| 118 | + <Route path="users/:username" file="routes/users+/$username.tsx" /> |
| 119 | + <Route |
| 120 | + path="users/:username/notes" |
| 121 | + file="routes/users+/$username_+/notes.tsx" |
| 122 | + > |
| 123 | + <Route |
| 124 | + path=":noteId" |
| 125 | + file="routes/users+/$username_+/notes.$noteId.tsx" |
| 126 | + /> |
| 127 | + <Route |
| 128 | + path=":noteId/edit" |
| 129 | + file="routes/users+/$username_+/notes.$noteId_.edit.tsx" |
| 130 | + /> |
| 131 | + <Route path="new" file="routes/users+/$username_+/notes.new.tsx" /> |
| 132 | + <Route index file="routes/users+/$username_+/notes.index.tsx" /> |
| 133 | + </Route> |
| 134 | + </Route> |
| 135 | +</Routes> |
| 136 | +``` |
| 137 | + |
| 138 | +Basically, remix-flat-routes hybrid routing allows us to get the best of both |
| 139 | +worlds: |
| 140 | + |
| 141 | +- Colocation of routes to the code they use |
| 142 | +- Organized folder structure to keep routes together as needed |
| 143 | + |
| 144 | +If you're familiar with the Remix routing convention, just think of it this way, |
| 145 | +remix-flat-routes converts `+/` to `.`. |
0 commit comments