Skip to content

Commit d47a918

Browse files
Make routes the default export in routes.ts (#12305)
1 parent 818d327 commit d47a918

File tree

22 files changed

+75
-78
lines changed

22 files changed

+75
-78
lines changed

decisions/0011-routes-ts.md

-10
Original file line numberDiff line numberDiff line change
@@ -48,16 +48,6 @@ Remix ships with a default set of file system routing conventions. While conveni
4848

4949
Any project using the Vite plugin must have a `routes.ts` file which exports an array of route config objects.
5050

51-
### Route config is exported via the `routes` export
52-
53-
We specifically chose to use the `routes` export instead of the more traditional `default` export you might expect in a config file. There are a couple of reasons for this:
54-
55-
1. The `RouteConfig` type can be annotated up-front and inline (`export const routes: RouteConfig = [...]`).
56-
57-
In contrast, default exports either require a variable to be declared first (`let routes: RouteConfig = ...; export default routes;`), or they require the use of a `satisfies` annotation at the _end_ of the file (`export default ... satisfies RouteConfig`) which can be easy to miss when dealing with large route configs.
58-
59-
2. In other areas of the framework we've come to prefer using named exports. We want to avoid introducing many different default exports that mean different things in different contexts. Named exports are much more self-documenting when looking at the file contents alone, especially if additional exports are added in the future.
60-
6151
### `routes.ts` is in the `app` directory
6252

6353
There are a few reasons for this:

docs/explanation/type-safety.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ import {
1616
route,
1717
} from "@react-router/dev/routes";
1818

19-
export const routes: RouteConfig = [
19+
export default [
2020
route("products/:id", "./routes/product.tsx"),
21-
];
21+
] satisfies RouteConfig;
2222
```
2323

2424
You can import route-specific types like so:

docs/how-to/file-route-conventions.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ Then use it to provide route config in your `app/routes.ts` file:
2020
import { type RouteConfig } from "@react-router/dev/routes";
2121
import { flatRoutes } from "@react-router/fs-routes";
2222

23-
export const routes: RouteConfig = flatRoutes();
23+
export default flatRoutes() satisfies RouteConfig;
2424
```
2525

2626
This will look for routes in the `app/routes` directory by default, but this can be configured via the `rootDirectory` option which is relative to your app directory:
@@ -29,9 +29,9 @@ This will look for routes in the `app/routes` directory by default, but this can
2929
import { type RouteConfig } from "@react-router/dev/routes";
3030
import { flatRoutes } from "@react-router/fs-routes";
3131

32-
export const routes: RouteConfig = flatRoutes({
32+
export default flatRoutes({
3333
rootDirectory: "file-routes",
34-
});
34+
}) satisfies RouteConfig;
3535
```
3636

3737
The rest of this guide will assume you're using the default `app/routes` directory.

docs/how-to/form-validation.md

+8-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,14 @@ This guide walks you through implementing form validation for a simple signup fo
1111
We'll start by creating a basic signup route with form.
1212

1313
```ts filename=routes.ts
14-
import { route } from "@react-router/dev/routes";
15-
16-
export const routes = [route("signup", "signup.tsx")];
14+
import {
15+
type RouteConfig,
16+
route,
17+
} from "@react-router/dev/routes";
18+
19+
export default [
20+
route("signup", "signup.tsx"),
21+
] satisfies RouteConfig;
1722
```
1823

1924
```tsx filename=signup.tsx

docs/index.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ import {
6666
prefix,
6767
} from "@react-router/dev/routes";
6868

69-
export const routes: RouteConfig = [
69+
export default [
7070
index("./home.tsx"),
7171
route("about", "./about.tsx"),
7272

@@ -81,7 +81,7 @@ export const routes: RouteConfig = [
8181
route(":city/:id", "./concerts/show.tsx")
8282
route("trending", "./concerts/trending.tsx"),
8383
]),
84-
];
84+
] satisfies RouteConfig;
8585
```
8686

8787
You'll have access to the Route Module API, which most of the other features are built on.

docs/start/framework/routing.md

+17-14
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,16 @@ order: 2
99

1010
Routes are configured in `app/routes.ts`. Routes have a url pattern to match the URL and a file path to the route module to define its behavior.
1111

12-
```tsx
13-
import { route } from "@react-router/dev/routes";
12+
```ts filename=app/routes.ts
13+
import {
14+
type RouteConfig,
15+
route,
16+
} from "@react-router/dev/routes";
1417

15-
export const routes = [
18+
export default [
1619
route("some/path", "./some/file.tsx"),
1720
// pattern ^ ^ module file
18-
];
21+
] satisfies RouteConfig;
1922
```
2023

2124
Here is a larger sample route config:
@@ -29,7 +32,7 @@ import {
2932
prefix,
3033
} from "@react-router/dev/routes";
3134

32-
export const routes: RouteConfig = [
35+
export default [
3336
index("./home.tsx"),
3437
route("about", "./about.tsx"),
3538

@@ -43,7 +46,7 @@ export const routes: RouteConfig = [
4346
route(":city", "./concerts/city.tsx"),
4447
route("trending", "./concerts/trending.tsx"),
4548
]),
46-
];
49+
] satisfies RouteConfig;
4750
```
4851

4952
If you prefer to define your routes via file naming conventions rather than configuration, the `@react-router/fs-routes` package provides a [file system routing convention.][file-route-conventions]
@@ -90,14 +93,14 @@ import {
9093
index,
9194
} from "@react-router/dev/routes";
9295

93-
export const routes: RouteConfig = [
96+
export default [
9497
// parent route
9598
route("dashboard", "./dashboard.tsx", [
9699
// child routes
97100
index("./home.tsx"),
98101
route("settings", "./settings.tsx"),
99102
]),
100-
];
103+
] satisfies RouteConfig;
101104
```
102105

103106
The path of the parent is automatically included in the child, so this config creates both `"/dashboard"` and `"/dashboard/settings"` URLs.
@@ -135,7 +138,7 @@ import {
135138
prefix,
136139
} from "@react-router/dev/routes";
137140

138-
export const routes: RouteConfig = [
141+
export default [
139142
layout("./marketing/layout.tsx", [
140143
index("./marketing/home.tsx"),
141144
route("contact", "./marketing/contact.tsx"),
@@ -147,7 +150,7 @@ export const routes: RouteConfig = [
147150
route(":pid/edit", "./projects/edit-project.tsx"),
148151
]),
149152
]),
150-
];
153+
] satisfies RouteConfig;
151154
```
152155

153156
## Index Routes
@@ -165,15 +168,15 @@ import {
165168
index,
166169
} from "@react-router/dev/routes";
167170

168-
export const routes: RouteConfig = [
171+
export default [
169172
// renders into the root.tsx Outlet at /
170173
index("./home.tsx"),
171174
route("dashboard", "./dashboard.tsx", [
172175
// renders into the dashboard.tsx Outlet at /dashboard
173176
index("./dashboard-home.tsx"),
174177
route("settings", "./dashboard-settings.tsx"),
175178
]),
176-
];
179+
] satisfies RouteConfig;
177180
```
178181

179182
Note that index routes can't have children.
@@ -191,7 +194,7 @@ import {
191194
prefix,
192195
} from "@react-router/dev/routes";
193196

194-
export const routes: RouteConfig = [
197+
export default [
195198
layout("./marketing/layout.tsx", [
196199
index("./marketing/home.tsx"),
197200
route("contact", "./marketing/contact.tsx"),
@@ -203,7 +206,7 @@ export const routes: RouteConfig = [
203206
route(":pid/edit", "./projects/edit-project.tsx"),
204207
]),
205208
]),
206-
];
209+
] satisfies RouteConfig;
207210
```
208211

209212
## Dynamic Segments

docs/upgrading/component-routes.md

+4-4
Original file line numberDiff line numberDiff line change
@@ -180,12 +180,12 @@ Create a file at `src/routes.ts` and add this:
180180
```ts filename=src/routes.ts
181181
import { type RouteConfig } from "@react-router/dev/routes";
182182

183-
export const routes: RouteConfig = [
183+
export default [
184184
{
185185
path: "*",
186186
file: "src/catchall.tsx",
187187
},
188-
];
188+
] satisfies RouteConfig;
189189
```
190190

191191
And then create the catchall route module and render your existing root App component within it.
@@ -224,7 +224,7 @@ You can move the definition to a `routes.ts` file:
224224
```tsx filename=src/routes.ts
225225
import { type RouteConfig } from "@react-router/dev/routes";
226226

227-
export const routes: RouteConfig = [
227+
export default [
228228
{
229229
path: "/pages/:id",
230230
file: "./containers/page.tsx",
@@ -233,7 +233,7 @@ export const routes: RouteConfig = [
233233
path: "*",
234234
file: "src/catchall.tsx",
235235
},
236-
];
236+
] satisfies RouteConfig;
237237
```
238238

239239
And then edit the route module to use the Route Module API:

docs/upgrading/remix.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -110,7 +110,7 @@ In React Router v7 you define your routes using the [`app/routes.ts`][routing] f
110110
import { type RouteConfig } from "@react-router/dev/routes";
111111
import { flatRoutes } from "@react-router/fs-routes";
112112

113-
export const routes: RouteConfig = flatRoutes();
113+
export default flatRoutes() satisfies RouteConfig;
114114
```
115115

116116
### Step 6 - Rename components in entry files

docs/upgrading/router-provider.md

+2-2
Original file line numberDiff line numberDiff line change
@@ -209,12 +209,12 @@ You can move the definition to a `routes.ts` file:
209209
```tsx filename=src/routes.ts
210210
import { type RouteConfig } from "@react-router/dev/routes";
211211

212-
export const routes: RouteConfig = [
212+
export default [
213213
{
214214
path: "/pages/:id",
215215
file: "./containers/page.tsx",
216216
},
217-
];
217+
] satisfies RouteConfig;
218218
```
219219

220220
And then edit the route module to use the Route Module API:

integration/fs-routes-test.ts

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ test.describe("fs-routes", () => {
3030
import { flatRoutes } from "@react-router/fs-routes";
3131
import { remixRoutesOptionAdapter } from "@react-router/remix-routes-option-adapter";
3232
33-
export const routes: RouteConfig = [
33+
export default [
3434
...await flatRoutes({
3535
ignoredRouteFiles: ["**/ignored-route.*"],
3636
}),
@@ -42,7 +42,7 @@ test.describe("fs-routes", () => {
4242
route("/remix/config/route", "remix-config-route.tsx")
4343
});
4444
})
45-
];
45+
] satisfies RouteConfig;
4646
`,
4747
"app/root.tsx": js`
4848
import { Links, Meta, Outlet, Scripts } from "react-router";
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import { type RouteConfig } from "@react-router/dev/routes";
22
import { flatRoutes } from "@react-router/fs-routes";
33

4-
export const routes: RouteConfig = flatRoutes();
4+
export default flatRoutes() satisfies RouteConfig;
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
import { type RouteConfig } from "@react-router/dev/routes";
22
import { flatRoutes } from "@react-router/fs-routes";
33

4-
export const routes: RouteConfig = flatRoutes();
4+
export default flatRoutes() satisfies RouteConfig;

integration/route-config-test.ts

+9-9
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,9 @@ test.describe("route config", () => {
5959
"app/routes.ts": js`
6060
import { type RouteConfig, index } from "@react-router/dev/routes";
6161
62-
export const routes: RouteConfig = [
62+
export default [
6363
index("test-route-1.tsx"),
64-
];
64+
] satisfies RouteConfig;
6565
`,
6666
"app/test-route-1.tsx": `
6767
export default () => <div data-test-route>Test route 1</div>
@@ -109,14 +109,14 @@ test.describe("route config", () => {
109109
let files: Files = async ({ port }) => ({
110110
"vite.config.js": await viteConfig.basic({ port }),
111111
"app/routes.ts": js`
112-
export { routes } from "./actual-routes";
112+
export { default } from "./actual-routes";
113113
`,
114114
"app/actual-routes.ts": js`
115115
import { type RouteConfig, index } from "@react-router/dev/routes";
116116
117-
export const routes: RouteConfig = [
117+
export default [
118118
index("test-route-1.tsx"),
119-
];
119+
] satisfies RouteConfig;
120120
`,
121121
"app/test-route-1.tsx": `
122122
export default () => <div data-test-route>Test route 1</div>
@@ -163,9 +163,9 @@ test.describe("route config", () => {
163163
"app/routes.ts": js`
164164
import { type RouteConfig, index } from "@react-router/dev/routes";
165165
166-
export const routes: RouteConfig = [
166+
export default [
167167
index("test-route-1.tsx"),
168-
];
168+
] satisfies RouteConfig;
169169
`,
170170
"app/test-route-1.tsx": `
171171
export default () => <div data-test-route>Test route 1</div>
@@ -224,9 +224,9 @@ test.describe("route config", () => {
224224
import path from "node:path";
225225
import { type RouteConfig, index } from "@react-router/dev/routes";
226226
227-
export const routes: RouteConfig = [
227+
export default [
228228
index(path.resolve(import.meta.dirname, "test-route.tsx")),
229-
];
229+
] satisfies RouteConfig;
230230
`,
231231
"app/test-route.tsx": `
232232
export default () => <div data-test-route>Test route</div>

0 commit comments

Comments
 (0)