@react-router/dev 7.11.0-pre.0 → 7.12.0-pre.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +49 -4
- package/dist/cli/index.js +5 -1
- package/dist/config.d.ts +11 -0
- package/dist/config.js +1 -1
- package/dist/routes.js +1 -1
- package/dist/vite/cloudflare.js +4 -1
- package/dist/vite.js +34 -21
- package/package.json +6 -6
package/CHANGELOG.md
CHANGED
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
# `@react-router/dev`
|
|
2
2
|
|
|
3
|
-
## 7.
|
|
3
|
+
## 7.12.0-pre.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- Add additional layer of CSRF protection by rejecting submissions to UI routes from external origins. If you need to permit access to specific external origins, you can specify them in the `react-router.config.ts` config `allowedActionOrigins` field. ([#14708](https://github.com/remix-run/react-router/pull/14708))
|
|
8
|
+
|
|
9
|
+
### Patch Changes
|
|
10
|
+
|
|
11
|
+
- Fix `Maximum call stack size exceeded` errors when HMR is triggered against code with cyclic imports ([#14522](https://github.com/remix-run/react-router/pull/14522))
|
|
12
|
+
- fix(vite): Skip SSR middleware in preview server for SPA mode ([#14673](https://github.com/remix-run/react-router/pull/14673))
|
|
13
|
+
- [UNSTABLE] Add a new `future.unstable_trailingSlashAwareDataRequests` flag to provide consistent behavior of `request.pathname` inside `middleware`, `loader`, and `action` functions on document and data requests when a trailing slash is present in the browser URL. ([#14644](https://github.com/remix-run/react-router/pull/14644))
|
|
14
|
+
|
|
15
|
+
Currently, your HTTP and `request` pathnames would be as follows for `/a/b/c` and `/a/b/c/`
|
|
16
|
+
|
|
17
|
+
| URL `/a/b/c` | **HTTP pathname** | **`request` pathname`** |
|
|
18
|
+
| ------------ | ----------------- | ----------------------- |
|
|
19
|
+
| **Document** | `/a/b/c` | `/a/b/c` ✅ |
|
|
20
|
+
| **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
|
|
21
|
+
|
|
22
|
+
| URL `/a/b/c/` | **HTTP pathname** | **`request` pathname`** |
|
|
23
|
+
| ------------- | ----------------- | ----------------------- |
|
|
24
|
+
| **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
|
|
25
|
+
| **Data** | `/a/b/c.data` | `/a/b/c` ⚠️ |
|
|
26
|
+
|
|
27
|
+
With this flag enabled, these pathnames will be made consistent though a new `_.data` format for client-side `.data` requests:
|
|
28
|
+
|
|
29
|
+
| URL `/a/b/c` | **HTTP pathname** | **`request` pathname`** |
|
|
30
|
+
| ------------ | ----------------- | ----------------------- |
|
|
31
|
+
| **Document** | `/a/b/c` | `/a/b/c` ✅ |
|
|
32
|
+
| **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
|
|
33
|
+
|
|
34
|
+
| URL `/a/b/c/` | **HTTP pathname** | **`request` pathname`** |
|
|
35
|
+
| ------------- | ------------------ | ----------------------- |
|
|
36
|
+
| **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
|
|
37
|
+
| **Data** | `/a/b/c/_.data` ⬅️ | `/a/b/c/` ✅ |
|
|
38
|
+
|
|
39
|
+
This a bug fix but we are putting it behind an opt-in flag because it has the potential to be a "breaking bug fix" if you are relying on the URL format for any other application or caching logic.
|
|
40
|
+
|
|
41
|
+
Enabling this flag also changes the format of client side `.data` requests from `/_root.data` to `/_.data` when navigating to `/` to align with the new format. This does not impact the `request` pathname which is still `/` in all cases.
|
|
42
|
+
|
|
43
|
+
- Updated dependencies:
|
|
44
|
+
- `react-router@7.12.0-pre.0`
|
|
45
|
+
- `@react-router/node@7.12.0-pre.0`
|
|
46
|
+
- `@react-router/serve@7.12.0-pre.0`
|
|
47
|
+
|
|
48
|
+
## 7.11.0
|
|
4
49
|
|
|
5
50
|
### Minor Changes
|
|
6
51
|
|
|
@@ -14,9 +59,9 @@
|
|
|
14
59
|
- `routeRSCServerRequest` replace `fetchServer` with `serverResponse` ([#14597](https://github.com/remix-run/react-router/pull/14597))
|
|
15
60
|
- rsc framewlrk mode - optimize react-server-dom-webpack if in project package.json ([#14656](https://github.com/remix-run/react-router/pull/14656))
|
|
16
61
|
- Updated dependencies:
|
|
17
|
-
- `react-router@7.11.0
|
|
18
|
-
- `@react-router/serve@7.11.0
|
|
19
|
-
- `@react-router/node@7.11.0
|
|
62
|
+
- `react-router@7.11.0`
|
|
63
|
+
- `@react-router/serve@7.11.0`
|
|
64
|
+
- `@react-router/node@7.11.0`
|
|
20
65
|
|
|
21
66
|
## 7.10.1
|
|
22
67
|
|
package/dist/cli/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
/**
|
|
3
|
-
* @react-router/dev v7.
|
|
3
|
+
* @react-router/dev v7.12.0-pre.0
|
|
4
4
|
*
|
|
5
5
|
* Copyright (c) Remix Software Inc.
|
|
6
6
|
*
|
|
@@ -506,10 +506,12 @@ async function resolveConfig({
|
|
|
506
506
|
let future = {
|
|
507
507
|
unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
|
|
508
508
|
unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
|
|
509
|
+
unstable_trailingSlashAwareDataRequests: userAndPresetConfigs.future?.unstable_trailingSlashAwareDataRequests ?? false,
|
|
509
510
|
v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
|
|
510
511
|
v8_splitRouteModules: userAndPresetConfigs.future?.v8_splitRouteModules ?? false,
|
|
511
512
|
v8_viteEnvironmentApi: userAndPresetConfigs.future?.v8_viteEnvironmentApi ?? false
|
|
512
513
|
};
|
|
514
|
+
let allowedActionOrigins = userAndPresetConfigs.allowedActionOrigins ?? false;
|
|
513
515
|
let reactRouterConfig = deepFreeze({
|
|
514
516
|
appDirectory,
|
|
515
517
|
basename: basename3,
|
|
@@ -523,6 +525,7 @@ async function resolveConfig({
|
|
|
523
525
|
serverBundles,
|
|
524
526
|
serverModuleFormat,
|
|
525
527
|
ssr,
|
|
528
|
+
allowedActionOrigins,
|
|
526
529
|
unstable_routeConfig: routeConfig
|
|
527
530
|
});
|
|
528
531
|
for (let preset of reactRouterUserConfig.presets ?? []) {
|
|
@@ -956,6 +959,7 @@ function generateServerBuild(ctx) {
|
|
|
956
959
|
export const routeDiscovery: ServerBuild["routeDiscovery"];
|
|
957
960
|
export const routes: ServerBuild["routes"];
|
|
958
961
|
export const ssr: ServerBuild["ssr"];
|
|
962
|
+
export const allowedActionOrigins: ServerBuild["allowedActionOrigins"];
|
|
959
963
|
export const unstable_getCriticalCss: ServerBuild["unstable_getCriticalCss"];
|
|
960
964
|
}
|
|
961
965
|
`;
|
package/dist/config.d.ts
CHANGED
|
@@ -39,6 +39,7 @@ type ServerModuleFormat = "esm" | "cjs";
|
|
|
39
39
|
interface FutureConfig {
|
|
40
40
|
unstable_optimizeDeps: boolean;
|
|
41
41
|
unstable_subResourceIntegrity: boolean;
|
|
42
|
+
unstable_trailingSlashAwareDataRequests: boolean;
|
|
42
43
|
/**
|
|
43
44
|
* Enable route middleware
|
|
44
45
|
*/
|
|
@@ -147,6 +148,11 @@ type ReactRouterConfig = {
|
|
|
147
148
|
* SPA without server-rendering. Default's to `true`.
|
|
148
149
|
*/
|
|
149
150
|
ssr?: boolean;
|
|
151
|
+
/**
|
|
152
|
+
* The allowed origins for actions / mutations. Does not apply to routes
|
|
153
|
+
* without a component. micromatch glob patterns are supported.
|
|
154
|
+
*/
|
|
155
|
+
allowedActionOrigins?: string[];
|
|
150
156
|
};
|
|
151
157
|
type ResolvedReactRouterConfig = Readonly<{
|
|
152
158
|
/**
|
|
@@ -212,6 +218,11 @@ type ResolvedReactRouterConfig = Readonly<{
|
|
|
212
218
|
* SPA without server-rendering. Default's to `true`.
|
|
213
219
|
*/
|
|
214
220
|
ssr: boolean;
|
|
221
|
+
/**
|
|
222
|
+
* The allowed origins for actions / mutations. Does not apply to routes
|
|
223
|
+
* without a component. micromatch glob patterns are supported.
|
|
224
|
+
*/
|
|
225
|
+
allowedActionOrigins: string[] | false;
|
|
215
226
|
/**
|
|
216
227
|
* The resolved array of route config entries exported from `routes.ts`
|
|
217
228
|
*/
|
package/dist/config.js
CHANGED
package/dist/routes.js
CHANGED
package/dist/vite/cloudflare.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v7.
|
|
2
|
+
* @react-router/dev v7.12.0-pre.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -535,10 +535,12 @@ async function resolveConfig({
|
|
|
535
535
|
let future = {
|
|
536
536
|
unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
|
|
537
537
|
unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
|
|
538
|
+
unstable_trailingSlashAwareDataRequests: userAndPresetConfigs.future?.unstable_trailingSlashAwareDataRequests ?? false,
|
|
538
539
|
v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
|
|
539
540
|
v8_splitRouteModules: userAndPresetConfigs.future?.v8_splitRouteModules ?? false,
|
|
540
541
|
v8_viteEnvironmentApi: userAndPresetConfigs.future?.v8_viteEnvironmentApi ?? false
|
|
541
542
|
};
|
|
543
|
+
let allowedActionOrigins = userAndPresetConfigs.allowedActionOrigins ?? false;
|
|
542
544
|
let reactRouterConfig = deepFreeze({
|
|
543
545
|
appDirectory,
|
|
544
546
|
basename,
|
|
@@ -552,6 +554,7 @@ async function resolveConfig({
|
|
|
552
554
|
serverBundles,
|
|
553
555
|
serverModuleFormat,
|
|
554
556
|
ssr,
|
|
557
|
+
allowedActionOrigins,
|
|
555
558
|
unstable_routeConfig: routeConfig
|
|
556
559
|
});
|
|
557
560
|
for (let preset of reactRouterUserConfig.presets ?? []) {
|
package/dist/vite.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/dev v7.
|
|
2
|
+
* @react-router/dev v7.12.0-pre.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -562,10 +562,12 @@ async function resolveConfig({
|
|
|
562
562
|
let future = {
|
|
563
563
|
unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
|
|
564
564
|
unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
|
|
565
|
+
unstable_trailingSlashAwareDataRequests: userAndPresetConfigs.future?.unstable_trailingSlashAwareDataRequests ?? false,
|
|
565
566
|
v8_middleware: userAndPresetConfigs.future?.v8_middleware ?? false,
|
|
566
567
|
v8_splitRouteModules: userAndPresetConfigs.future?.v8_splitRouteModules ?? false,
|
|
567
568
|
v8_viteEnvironmentApi: userAndPresetConfigs.future?.v8_viteEnvironmentApi ?? false
|
|
568
569
|
};
|
|
570
|
+
let allowedActionOrigins = userAndPresetConfigs.allowedActionOrigins ?? false;
|
|
569
571
|
let reactRouterConfig = deepFreeze({
|
|
570
572
|
appDirectory,
|
|
571
573
|
basename: basename3,
|
|
@@ -579,6 +581,7 @@ async function resolveConfig({
|
|
|
579
581
|
serverBundles,
|
|
580
582
|
serverModuleFormat,
|
|
581
583
|
ssr,
|
|
584
|
+
allowedActionOrigins,
|
|
582
585
|
unstable_routeConfig: routeConfig
|
|
583
586
|
});
|
|
584
587
|
for (let preset of reactRouterUserConfig.presets ?? []) {
|
|
@@ -966,6 +969,7 @@ function generateServerBuild(ctx) {
|
|
|
966
969
|
export const routeDiscovery: ServerBuild["routeDiscovery"];
|
|
967
970
|
export const routes: ServerBuild["routes"];
|
|
968
971
|
export const ssr: ServerBuild["ssr"];
|
|
972
|
+
export const allowedActionOrigins: ServerBuild["allowedActionOrigins"];
|
|
969
973
|
export const unstable_getCriticalCss: ServerBuild["unstable_getCriticalCss"];
|
|
970
974
|
}
|
|
971
975
|
`;
|
|
@@ -2921,7 +2925,9 @@ var reactRouterVitePlugin = () => {
|
|
|
2921
2925
|
href: "${ctx.publicPath}@react-router/critical.css?pathname=" + pathname,
|
|
2922
2926
|
};
|
|
2923
2927
|
}
|
|
2924
|
-
` : ""}
|
|
2928
|
+
` : ""}
|
|
2929
|
+
export const allowedActionOrigins = ${JSON.stringify(ctx.reactRouterConfig.allowedActionOrigins)};
|
|
2930
|
+
`;
|
|
2925
2931
|
};
|
|
2926
2932
|
let loadViteManifest = async (directory) => {
|
|
2927
2933
|
let manifestContents = await (0, import_promises2.readFile)(
|
|
@@ -3536,6 +3542,9 @@ var reactRouterVitePlugin = () => {
|
|
|
3536
3542
|
},
|
|
3537
3543
|
configurePreviewServer(previewServer) {
|
|
3538
3544
|
return () => {
|
|
3545
|
+
if (!ctx.reactRouterConfig.ssr) {
|
|
3546
|
+
return;
|
|
3547
|
+
}
|
|
3539
3548
|
previewServer.middlewares.use(async (req, res, next) => {
|
|
3540
3549
|
try {
|
|
3541
3550
|
let serverBuildDirectory = getServerBuildDirectory(
|
|
@@ -4099,10 +4108,8 @@ var reactRouterVitePlugin = () => {
|
|
|
4099
4108
|
if (this.environment.name !== "ssr" && modules.length <= 0) {
|
|
4100
4109
|
return;
|
|
4101
4110
|
}
|
|
4102
|
-
let clientModules =
|
|
4103
|
-
|
|
4104
|
-
(mod) => getParentClientNodes(server.environments.client.moduleGraph, mod)
|
|
4105
|
-
)
|
|
4111
|
+
let clientModules = modules.flatMap(
|
|
4112
|
+
(mod) => getParentClientNodes(server.environments.client.moduleGraph, mod)
|
|
4106
4113
|
);
|
|
4107
4114
|
for (let clientModule of clientModules) {
|
|
4108
4115
|
server.environments.client.reloadModule(clientModule);
|
|
@@ -4113,30 +4120,22 @@ var reactRouterVitePlugin = () => {
|
|
|
4113
4120
|
warnOnClientSourceMaps()
|
|
4114
4121
|
];
|
|
4115
4122
|
};
|
|
4116
|
-
function getParentClientNodes(clientModuleGraph, module2) {
|
|
4123
|
+
function getParentClientNodes(clientModuleGraph, module2, seenNodes = /* @__PURE__ */ new Set()) {
|
|
4117
4124
|
if (!module2.id) {
|
|
4118
4125
|
return [];
|
|
4119
4126
|
}
|
|
4127
|
+
if (seenNodes.has(module2.url)) {
|
|
4128
|
+
return [];
|
|
4129
|
+
}
|
|
4130
|
+
seenNodes.add(module2.url);
|
|
4120
4131
|
let clientModule = clientModuleGraph.getModuleById(module2.id);
|
|
4121
4132
|
if (clientModule) {
|
|
4122
4133
|
return [clientModule];
|
|
4123
4134
|
}
|
|
4124
4135
|
return [...module2.importers].flatMap(
|
|
4125
|
-
(importer) => getParentClientNodes(clientModuleGraph, importer)
|
|
4136
|
+
(importer) => getParentClientNodes(clientModuleGraph, importer, seenNodes)
|
|
4126
4137
|
);
|
|
4127
4138
|
}
|
|
4128
|
-
function uniqueNodes(nodes) {
|
|
4129
|
-
let nodeUrls = /* @__PURE__ */ new Set();
|
|
4130
|
-
let unique = [];
|
|
4131
|
-
for (let node of nodes) {
|
|
4132
|
-
if (nodeUrls.has(node.url)) {
|
|
4133
|
-
continue;
|
|
4134
|
-
}
|
|
4135
|
-
nodeUrls.add(node.url);
|
|
4136
|
-
unique.push(node);
|
|
4137
|
-
}
|
|
4138
|
-
return unique;
|
|
4139
|
-
}
|
|
4140
4139
|
function addRefreshWrapper(reactRouterConfig, code, id) {
|
|
4141
4140
|
let route = getRoute(reactRouterConfig, id);
|
|
4142
4141
|
let acceptExports = route ? CLIENT_NON_COMPONENT_EXPORTS : [];
|
|
@@ -4411,7 +4410,21 @@ function getStaticPrerenderPaths(routes) {
|
|
|
4411
4410
|
};
|
|
4412
4411
|
}
|
|
4413
4412
|
async function prerenderData(handler, prerenderPath, onlyRoutes, clientBuildDirectory, reactRouterConfig, viteConfig, requestInit) {
|
|
4414
|
-
let
|
|
4413
|
+
let dataRequestPath;
|
|
4414
|
+
if (reactRouterConfig.future.unstable_trailingSlashAwareDataRequests) {
|
|
4415
|
+
if (prerenderPath.endsWith("/")) {
|
|
4416
|
+
dataRequestPath = `${prerenderPath}_.data`;
|
|
4417
|
+
} else {
|
|
4418
|
+
dataRequestPath = `${prerenderPath}.data`;
|
|
4419
|
+
}
|
|
4420
|
+
} else {
|
|
4421
|
+
if (prerenderPath === "/") {
|
|
4422
|
+
dataRequestPath = "/_root.data";
|
|
4423
|
+
} else {
|
|
4424
|
+
dataRequestPath = `${prerenderPath.replace(/\/$/, "")}.data`;
|
|
4425
|
+
}
|
|
4426
|
+
}
|
|
4427
|
+
let normalizedPath = `${reactRouterConfig.basename}${dataRequestPath}`.replace(/\/\/+/g, "/");
|
|
4415
4428
|
let url2 = new URL(`http://localhost${normalizedPath}`);
|
|
4416
4429
|
if (onlyRoutes?.length) {
|
|
4417
4430
|
url2.searchParams.set("_routes", onlyRoutes.join(","));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-router/dev",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.12.0-pre.0",
|
|
4
4
|
"description": "Dev tools and CLI for React Router",
|
|
5
5
|
"homepage": "https://reactrouter.com",
|
|
6
6
|
"bugs": {
|
|
@@ -92,7 +92,7 @@
|
|
|
92
92
|
"tinyglobby": "^0.2.14",
|
|
93
93
|
"valibot": "^1.2.0",
|
|
94
94
|
"vite-node": "^3.2.2",
|
|
95
|
-
"@react-router/node": "7.
|
|
95
|
+
"@react-router/node": "7.12.0-pre.0"
|
|
96
96
|
},
|
|
97
97
|
"devDependencies": {
|
|
98
98
|
"@types/babel__core": "^7.20.5",
|
|
@@ -116,8 +116,8 @@
|
|
|
116
116
|
"vite": "^6.3.0",
|
|
117
117
|
"wireit": "0.14.9",
|
|
118
118
|
"wrangler": "^4.23.0",
|
|
119
|
-
"@react-router/serve": "7.
|
|
120
|
-
"react-router": "^7.
|
|
119
|
+
"@react-router/serve": "7.12.0-pre.0",
|
|
120
|
+
"react-router": "^7.12.0-pre.0"
|
|
121
121
|
},
|
|
122
122
|
"peerDependencies": {
|
|
123
123
|
"@vitejs/plugin-rsc": "~0.5.7",
|
|
@@ -125,8 +125,8 @@
|
|
|
125
125
|
"typescript": "^5.1.0",
|
|
126
126
|
"vite": "^5.1.0 || ^6.0.0 || ^7.0.0",
|
|
127
127
|
"wrangler": "^3.28.2 || ^4.0.0",
|
|
128
|
-
"@react-router/serve": "^7.
|
|
129
|
-
"react-router": "^7.
|
|
128
|
+
"@react-router/serve": "^7.12.0-pre.0",
|
|
129
|
+
"react-router": "^7.12.0-pre.0"
|
|
130
130
|
},
|
|
131
131
|
"peerDependenciesMeta": {
|
|
132
132
|
"@vitejs/plugin-rsc": {
|