You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
- Fix `react-router-serve` handling of prerendered HTML files by removing the `redirect: false` option so it now falls back on the default `redirect: true` behavior of redirecting from `/folder` -> `/folder/` which will then pick up `/folder/index.html` from disk. See https://expressjs.com/en/resources/middleware/serve-static.html
8
+
- Proxy prerendered loader data into prerender pass for HTML files to avoid double-invocations of the loader at build time
Copy file name to clipboardExpand all lines: docs/misc/pre-rendering.md
+2-14Lines changed: 2 additions & 14 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -92,7 +92,7 @@ If you pre-render all of the paths in your application, you can deploy your `bui
92
92
93
93
### Serving via react-router-serve
94
94
95
-
By default, `react-router-serve` will serve these files via [`express.static`][express-static] and any paths that do not match a static file will fall through to the Remix handler.
95
+
By default, `react-router-serve` will serve these files via [`express.static`][express-static] and any paths that do not match a static file will fall through to the React Router handler.
96
96
97
97
This even allows you to run a hybrid setup where _some_ of your routes are pre-rendered and others are dynamically rendered at runtime. For example, you could prerender anything inside `/blog/*` and server-render anything inside `/auth/*`.
98
98
@@ -111,19 +111,7 @@ app.use(
111
111
);
112
112
113
113
// Serve static HTML and .data requests without Cache-Control
114
-
app.use(
115
-
"/",
116
-
express.static("build/client", {
117
-
// Don't redirect directory index.html requests to include a trailing slash
118
-
redirect:false,
119
-
setHeaders:function (res, path) {
120
-
// Add the proper Content-Type for turbo-stream data responses
121
-
if (path.endsWith(".data")) {
122
-
res.set("Content-Type", "text/x-turbo");
123
-
}
124
-
},
125
-
})
126
-
);
114
+
app.use("/", express.static("build/client"));
127
115
128
116
// Serve remaining unhandled requests via your React Router handler
@@ -136,20 +137,21 @@ Every route in `routes.ts` is nested inside the special `app/root.tsx` module.
136
137
137
138
Using `layout`, layout routes create new nesting for their children, but they don't add any segments to the URL. It's like the root route but they can be added at any level.
If a path segment starts with `:` then it becomes a "dynamic segment". When the route matches the URL, the dynamic segment will be parsed from the URL and provided as `params` to other router APIs.
Also known as "catchall" and "star" segments. If a route path pattern ends with `/*` then it will match any characters following the `/`, including other `/` characters.
<docs-warning>This guide is still in development</docs-warning>
8
+
<docs-warning>This guide is still in development and is subject to change as React Router stabilizes prior to the `7.0.0` stable release</docs-warning>
9
9
10
-
After the final React Router v7 release, we will go back to Remix to add future flags to any changed APIs.
10
+
Our intention is for the **Remix v2 -> React Router v7** upgrade path to be as non-breaking as possible via the use of [Future Flags][future-flags] and codemods for minor and straightforward code adjustments. To best prepare for this eventual upgrade, you can start by adopting all of the existing [Remix v2 Future Flags][v2-future-flags].
11
11
12
-
If you want to attempt the rocky migration now, the following table will be helpful:
If you want to attempt the (potentially rocky) migration now, the following steps should get you most of the way there. If you run into issues please let us know in [Discord][remix-discord] or [Github][github-new-issue].
20
15
21
-
Also note that nearly all modules your app needs come from `react-router` now instead of `@remix-run/node` and `@remix-run/cloudflare`, so try to import from there first.
16
+
### Step 1 - Adopt future flags
17
+
18
+
Adopt all existing [future flags][v2-future-flags] in your Remix v2 application.
19
+
20
+
### Step 2 - Update dependencies
21
+
22
+
You'll need to update your dependencies from the `@remix-run/*` packages to `react-router` and `@react-router/*` packages in `package.json` and in your code where you import from packages:
Most of the "shared" APIs that used to be re-exported through the runtime-specific packages (`@remix-run/node`, `@remix-run/cloudflare`, etc.) have all been collapsed into `react-router` in v7. So instead of importing from `@react-router/node` or `@react-router/cloudflare`, you'll import those directly from `react-router`.
22
37
23
38
```diff
24
39
-import { redirect } from "@react-router/node";
25
40
+import { redirect } from "react-router";
26
41
```
42
+
43
+
The only APIs should be importing from the runtime-specific packages in v7 are APIs that are specific to that runtime, such as `createFileSessionStorage` for Node and `createWorkersKVSessionStorage` for Cloudflare.
Update the import and rename the plugin in your `vite.config.ts`:
59
+
60
+
```diff
61
+
-import { vitePlugin as remix } from "@remix-run/dev";
62
+
+import { reactRouter } from "@react-router/dev/vite";
63
+
import { defineConfig } from "vite";
64
+
import tsconfigPaths from "vite-tsconfig-paths";
65
+
66
+
export default defineConfig({
67
+
plugins: [
68
+
- remix({
69
+
- future: {
70
+
- // all future flags adopted
71
+
- },
72
+
- }),
73
+
+ reactRouter(),
74
+
tsconfigPaths(),
75
+
],
76
+
});
77
+
```
78
+
79
+
### Step 5 - Add a `routes.ts` file
80
+
81
+
In React Router v7 you define your routes using the [`app/routes.ts`][routing] file. For backwards-compatibility and for folks who prefer [file-based conventions][fs-routing], you can opt-into the same "flat routes" convention you are using in Remix v2 via the new `@react-router/fs-routes` package:
We have introduced some major changes to improve the type story in v7, but we're still working on making sure the path to adopt them is as smooth as possible prior to a stable v7 release. You can read more about the new type story in the [v7 draft release notes][v7-changelog-types] and if it's not a huge lift, your best bet for types in v7 is to migrate to that approach across the board.
104
+
105
+
For the time being we don't have a great story to _incrementally_ migrate data types to the v7 prerelease. We never brought the generics on data APIs (`useLoaderData`, `useFetcher`, `Await`, etc.) over from Remix to React Router because we knew that we could do better than what Remix v2 had, and we wanted to ensure that we didn't ship APIs in React Router just to yank them out. Now that we have a better idea of the type story in React Router v7, we're better able to see what the migration path looks like and we plan on shipping improvements in this area in an upcoming v7 prerelease.
106
+
107
+
Currently, when you upgrade to React Router v7 you're going to get typescript yelling at you a bunch for these missing generics that existed in your Remix v2 app code. For now, you have 2 options to continue testing out the prerelease:
108
+
109
+
**Option 1 - Ignore the type errors with `@ts-expect-error` or `@ts-ignore`**
110
+
111
+
```diff
112
+
+// @ts-expect-error
113
+
let data = useLoaderData<typeof loader>();
114
+
```
115
+
116
+
**Option 2 - Remove the generics and cast the types manually**
117
+
118
+
```diff
119
+
-let data = useLoaderData<typeof loader>();
120
+
+let data = useLoaderData() as ReturnType<Awaited<typeof loader>>;
Copy file name to clipboardExpand all lines: docs/upgrading/vite-router-provider.md
+1-1Lines changed: 1 addition & 1 deletion
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -230,7 +230,7 @@ The first few routes you migrate are the hardest because you often have to acces
230
230
231
231
## Enable SSR and/or Pre-rendering
232
232
233
-
If you want to enable server rendering and static pre-rendering, you can do so with the `ssr` and `prerender` options in the bundler plugin. For SSR you'll need to also deploy the server build to a server. See [Deploying](./deploying) for more information.
233
+
If you want to enable server rendering and static pre-rendering, you can do so with the `ssr` and `prerender` options in the bundler plugin. For SSR you'll need to also deploy the server build to a server. See [Deploying](../start/deploying) for more information.
0 commit comments