@c0va23/react-router-dev 7.13.1 → 7.13.2

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 CHANGED
@@ -1,5 +1,57 @@
1
1
  # `@react-router/dev`
2
2
 
3
+ ## 7.13.2
4
+
5
+ ### Patch Changes
6
+
7
+ - Fix `react-router dev` crash when Unix socket files exist in the project root ([#14854](https://github.com/remix-run/react-router/pull/14854))
8
+
9
+ - Escape redirect locations in prerendered redirect HTML ([#14880](https://github.com/remix-run/react-router/pull/14880))
10
+
11
+ - Add `future.unstable_passThroughRequests` flag ([#14775](https://github.com/remix-run/react-router/pull/14775))
12
+
13
+ By default, React Router normalizes the `request.url` passed to your `loader`, `action`, and `middleware` functions by removing React Router's internal implementation details (`.data` suffixes, `index` + `_routes` query params).
14
+
15
+ Enabling this flag removes that normalization and passes the raw HTTP `request` instance to your handlers. This provides a few benefits:
16
+
17
+ - Reduces server-side overhead by eliminating multiple `new Request()` calls on the critical path
18
+ - Allows you to distinguish document from data requests in your handlers base don the presence of a `.data` suffix (useful for observability purposes)
19
+
20
+ If you were previously relying on the normalization of `request.url`, you can switch to use the new sibling `unstable_url` parameter which contains a `URL` instance representing the normalized location:
21
+
22
+ ```tsx
23
+ // ❌ Before: you could assume there was no `.data` suffix in `request.url`
24
+ export async function loader({ request }: Route.LoaderArgs) {
25
+ let url = new URL(request.url);
26
+ if (url.pathname === "/path") {
27
+ // This check will fail with the flag enabled because the `.data` suffix will
28
+ // exist on data requests
29
+ }
30
+ }
31
+
32
+ // ✅ After: use `unstable_url` for normalized routing logic and `request.url`
33
+ // for raw routing logic
34
+ export async function loader({ request, unstable_url }: Route.LoaderArgs) {
35
+ if (unstable_url.pathname === "/path") {
36
+ // This will always have the `.data` suffix stripped
37
+ }
38
+
39
+ // And now you can distinguish between document versus data requests
40
+ let isDataRequest = new URL(request.url).pathname.endsWith(".data");
41
+ }
42
+ ```
43
+
44
+ - Add a new `unstable_url: URL` parameter to route handler methods (`loader`, `action`, `middleware`, etc.) representing the normalized URL the application is navigating to or fetching, with React Router implementation details removed (`.data`suffix, `index`/`_routes` query params) ([#14775](https://github.com/remix-run/react-router/pull/14775))
45
+
46
+ This is being added alongside the new `future.unstable_passthroughRequests` future flag so that users still have a way to access the normalized URL when that flag is enabled and non-normalized `request`'s are being passed to your handlers. When adopting this flag, you will only need to start leveraging this new parameter if you are relying on the normalization of `request.url` in your application code.
47
+
48
+ If you don't have the flag enabled, then `unstable_url` will match `request.url`.
49
+
50
+ - Updated dependencies:
51
+ - `react-router@7.13.2`
52
+ - `@react-router/node@7.13.2`
53
+ - `@react-router/serve@7.13.2`
54
+
3
55
  ## 7.13.1
4
56
 
5
57
  ### Patch Changes
@@ -37,25 +89,25 @@
37
89
 
38
90
  | URL `/a/b/c` | **HTTP pathname** | **`request` pathname\`** |
39
91
  | ------------ | ----------------- | ------------------------ |
40
- | **Document** | `/a/b/c` | `/a/b/c` ✅ |
41
- | **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
92
+ | **Document** | `/a/b/c` | `/a/b/c` ✅ |
93
+ | **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
42
94
 
43
95
  | URL `/a/b/c/` | **HTTP pathname** | **`request` pathname\`** |
44
96
  | ------------- | ----------------- | ------------------------ |
45
- | **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
97
+ | **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
46
98
  | **Data** | `/a/b/c.data` | `/a/b/c` ⚠️ |
47
99
 
48
100
  With this flag enabled, these pathnames will be made consistent though a new `_.data` format for client-side `.data` requests:
49
101
 
50
102
  | URL `/a/b/c` | **HTTP pathname** | **`request` pathname\`** |
51
103
  | ------------ | ----------------- | ------------------------ |
52
- | **Document** | `/a/b/c` | `/a/b/c` ✅ |
53
- | **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
104
+ | **Document** | `/a/b/c` | `/a/b/c` ✅ |
105
+ | **Data** | `/a/b/c.data` | `/a/b/c` ✅ |
54
106
 
55
107
  | URL `/a/b/c/` | **HTTP pathname** | **`request` pathname\`** |
56
108
  | ------------- | ------------------ | ------------------------ |
57
- | **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
58
- | **Data** | `/a/b/c/_.data` ⬅️ | `/a/b/c/` ✅ |
109
+ | **Document** | `/a/b/c/` | `/a/b/c/` ✅ |
110
+ | **Data** | `/a/b/c/_.data` ⬅️ | `/a/b/c/` ✅ |
59
111
 
60
112
  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.
61
113
 
@@ -313,6 +365,7 @@
313
365
  - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215))
314
366
 
315
367
  We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use:
368
+
316
369
  - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider)
317
370
  - [`createContext`](https://reactrouter.com/api/utils/createContext)
318
371
  - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option
@@ -1055,6 +1108,7 @@
1055
1108
  ```
1056
1109
 
1057
1110
  This initial implementation targets type inference for:
1111
+
1058
1112
  - `Params` : Path parameters from your routing config in `routes.ts` including file-based routing
1059
1113
  - `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module
1060
1114
  - `ActionData` : Action data from `action` and/or `clientAction` within your route module
@@ -1069,6 +1123,7 @@
1069
1123
  ```
1070
1124
 
1071
1125
  Check out our docs for more:
1126
+
1072
1127
  - [_Explanations > Type Safety_](https://reactrouter.com/dev/guides/explanation/type-safety)
1073
1128
  - [_How-To > Setting up type safety_](https://reactrouter.com/dev/guides/how-to/setting-up-type-safety)
1074
1129
 
@@ -1268,6 +1323,7 @@
1268
1323
  - Vite: Provide `Unstable_ServerBundlesFunction` and `Unstable_VitePluginConfig` types ([#8654](https://github.com/remix-run/remix/pull/8654))
1269
1324
 
1270
1325
  - Vite: add `--sourcemapClient` and `--sourcemapServer` flags to `remix vite:build` ([#8613](https://github.com/remix-run/remix/pull/8613))
1326
+
1271
1327
  - `--sourcemapClient`
1272
1328
 
1273
1329
  - `--sourcemapClient=inline`
@@ -1604,6 +1660,7 @@
1604
1660
  - Add support for `clientLoader`/`clientAction`/`HydrateFallback` route exports ([RFC](https://github.com/remix-run/remix/discussions/7634)) ([#8173](https://github.com/remix-run/remix/pull/8173))
1605
1661
 
1606
1662
  Remix now supports loaders/actions that run on the client (in addition to, or instead of the loader/action that runs on the server). While we still recommend server loaders/actions for the majority of your data needs in a Remix app - these provide some levers you can pull for more advanced use-cases such as:
1663
+
1607
1664
  - Leveraging a data source local to the browser (i.e., `localStorage`)
1608
1665
  - Managing a client-side cache of server data (like `IndexedDB`)
1609
1666
  - Bypassing the Remix server in a BFF setup and hitting your API directly from the browser
@@ -2007,6 +2064,7 @@
2007
2064
  - Output esbuild metafiles for bundle analysis ([#6772](https://github.com/remix-run/remix/pull/6772))
2008
2065
 
2009
2066
  Written to server build directory (`build/` by default):
2067
+
2010
2068
  - `metafile.css.json`
2011
2069
  - `metafile.js.json` (browser JS)
2012
2070
  - `metafile.server.json` (server JS)
@@ -2104,6 +2162,7 @@
2104
2162
  - built-in tls support ([#6483](https://github.com/remix-run/remix/pull/6483))
2105
2163
 
2106
2164
  New options:
2165
+
2107
2166
  - `--tls-key` / `tlsKey`: TLS key
2108
2167
  - `--tls-cert` / `tlsCert`: TLS Certificate
2109
2168
 
@@ -2374,6 +2433,7 @@
2374
2433
  ```
2375
2434
 
2376
2435
  The dev server will:
2436
+
2377
2437
  - force `NODE_ENV=development` and warn you if it was previously set to something else
2378
2438
  - rebuild your app whenever your Remix app code changes
2379
2439
  - restart your app server whenever rebuilds succeed
package/dist/cli/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  #!/usr/bin/env node
2
2
  /**
3
- * @react-router/dev v7.13.1
3
+ * @react-router/dev v7.13.2
4
4
  *
5
5
  * Copyright (c) Remix Software Inc.
6
6
  *
@@ -505,6 +505,7 @@ async function resolveConfig({
505
505
  }
506
506
  let future = {
507
507
  unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
508
+ unstable_passThroughRequests: userAndPresetConfigs.future?.unstable_passThroughRequests ?? false,
508
509
  unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
509
510
  unstable_trailingSlashAwareDataRequests: userAndPresetConfigs.future?.unstable_trailingSlashAwareDataRequests ?? false,
510
511
  unstable_previewServerPrerendering: userAndPresetConfigs.future?.unstable_previewServerPrerendering ?? false,
@@ -586,13 +587,11 @@ async function createConfigLoader({
586
587
  if (!fsWatcher) {
587
588
  fsWatcher = import_chokidar.default.watch([root, appDirectory], {
588
589
  ignoreInitial: true,
589
- ignored: (path10) => {
590
- let dirname5 = import_pathe3.default.dirname(path10);
591
- return !dirname5.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
592
- // that are at the root level, not nested in subdirectories
593
- path10 !== root && // Watch the root directory itself
594
- dirname5 !== root;
595
- }
590
+ ignored: (path10) => isIgnoredByWatcher(path10, { root, appDirectory })
591
+ });
592
+ fsWatcher.on("error", (error) => {
593
+ let message = error instanceof Error ? error.message : String(error);
594
+ console.warn(import_picocolors.default.yellow(`File watcher error: ${message}`));
596
595
  });
597
596
  fsWatcher.on("all", async (...args) => {
598
597
  let [event, rawFilepath] = args;
@@ -733,6 +732,25 @@ function isEntryFileDependency(moduleGraph, entryFilepath, filepath, visited = /
733
732
  }
734
733
  return false;
735
734
  }
735
+ function isIgnoredByWatcher(path10, { root, appDirectory }) {
736
+ let dirname5 = import_pathe3.default.dirname(path10);
737
+ let ignoredByPath = !dirname5.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
738
+ // that are at the root level, not nested in subdirectories
739
+ path10 !== root && // Watch the root directory itself
740
+ dirname5 !== root;
741
+ if (ignoredByPath) {
742
+ return true;
743
+ }
744
+ try {
745
+ let stat = import_node_fs.default.statSync(path10, { throwIfNoEntry: false });
746
+ if (stat && !stat.isFile() && !stat.isDirectory()) {
747
+ return true;
748
+ }
749
+ } catch {
750
+ return true;
751
+ }
752
+ return false;
753
+ }
736
754
  var import_node_fs, import_node_child_process, import_pathe3, import_chokidar, import_picocolors, import_pick2, import_omit, import_cloneDeep, import_isEqual, excludedConfigPresetKeys, mergeReactRouterConfig, deepFreeze, entryExts;
737
755
  var init_config = __esm({
738
756
  "config/config.ts"() {
package/dist/config.d.ts CHANGED
@@ -38,6 +38,7 @@ type ServerBundlesBuildManifest = BaseBuildManifest & {
38
38
  type ServerModuleFormat = "esm" | "cjs";
39
39
  interface FutureConfig {
40
40
  unstable_optimizeDeps: boolean;
41
+ unstable_passThroughRequests: boolean;
41
42
  unstable_subResourceIntegrity: boolean;
42
43
  unstable_trailingSlashAwareDataRequests: boolean;
43
44
  /**
package/dist/config.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v7.13.1
2
+ * @react-router/dev v7.13.2
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
package/dist/routes.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v7.13.1
2
+ * @react-router/dev v7.13.2
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v7.13.1
2
+ * @react-router/dev v7.13.2
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -531,6 +531,7 @@ async function resolveConfig({
531
531
  }
532
532
  let future = {
533
533
  unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
534
+ unstable_passThroughRequests: userAndPresetConfigs.future?.unstable_passThroughRequests ?? false,
534
535
  unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
535
536
  unstable_trailingSlashAwareDataRequests: userAndPresetConfigs.future?.unstable_trailingSlashAwareDataRequests ?? false,
536
537
  unstable_previewServerPrerendering: userAndPresetConfigs.future?.unstable_previewServerPrerendering ?? false,
@@ -612,13 +613,11 @@ async function createConfigLoader({
612
613
  if (!fsWatcher) {
613
614
  fsWatcher = import_chokidar.default.watch([root, appDirectory], {
614
615
  ignoreInitial: true,
615
- ignored: (path3) => {
616
- let dirname = import_pathe3.default.dirname(path3);
617
- return !dirname.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
618
- // that are at the root level, not nested in subdirectories
619
- path3 !== root && // Watch the root directory itself
620
- dirname !== root;
621
- }
616
+ ignored: (path3) => isIgnoredByWatcher(path3, { root, appDirectory })
617
+ });
618
+ fsWatcher.on("error", (error) => {
619
+ let message = error instanceof Error ? error.message : String(error);
620
+ console.warn(import_picocolors.default.yellow(`File watcher error: ${message}`));
622
621
  });
623
622
  fsWatcher.on("all", async (...args) => {
624
623
  let [event, rawFilepath] = args;
@@ -760,6 +759,25 @@ function isEntryFileDependency(moduleGraph, entryFilepath, filepath, visited = /
760
759
  }
761
760
  return false;
762
761
  }
762
+ function isIgnoredByWatcher(path3, { root, appDirectory }) {
763
+ let dirname = import_pathe3.default.dirname(path3);
764
+ let ignoredByPath = !dirname.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
765
+ // that are at the root level, not nested in subdirectories
766
+ path3 !== root && // Watch the root directory itself
767
+ dirname !== root;
768
+ if (ignoredByPath) {
769
+ return true;
770
+ }
771
+ try {
772
+ let stat = import_node_fs.default.statSync(path3, { throwIfNoEntry: false });
773
+ if (stat && !stat.isFile() && !stat.isDirectory()) {
774
+ return true;
775
+ }
776
+ } catch {
777
+ return true;
778
+ }
779
+ return false;
780
+ }
763
781
 
764
782
  // vite/cloudflare-dev-proxy.ts
765
783
  var serverBuildId = "virtual:react-router/server-build";
package/dist/vite.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /**
2
- * @react-router/dev v7.13.1
2
+ * @react-router/dev v7.13.2
3
3
  *
4
4
  * Copyright (c) Remix Software Inc.
5
5
  *
@@ -560,6 +560,7 @@ async function resolveConfig({
560
560
  }
561
561
  let future = {
562
562
  unstable_optimizeDeps: userAndPresetConfigs.future?.unstable_optimizeDeps ?? false,
563
+ unstable_passThroughRequests: userAndPresetConfigs.future?.unstable_passThroughRequests ?? false,
563
564
  unstable_subResourceIntegrity: userAndPresetConfigs.future?.unstable_subResourceIntegrity ?? false,
564
565
  unstable_trailingSlashAwareDataRequests: userAndPresetConfigs.future?.unstable_trailingSlashAwareDataRequests ?? false,
565
566
  unstable_previewServerPrerendering: userAndPresetConfigs.future?.unstable_previewServerPrerendering ?? false,
@@ -641,13 +642,11 @@ async function createConfigLoader({
641
642
  if (!fsWatcher) {
642
643
  fsWatcher = import_chokidar.default.watch([root, appDirectory], {
643
644
  ignoreInitial: true,
644
- ignored: (path10) => {
645
- let dirname4 = import_pathe3.default.dirname(path10);
646
- return !dirname4.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
647
- // that are at the root level, not nested in subdirectories
648
- path10 !== root && // Watch the root directory itself
649
- dirname4 !== root;
650
- }
645
+ ignored: (path10) => isIgnoredByWatcher(path10, { root, appDirectory })
646
+ });
647
+ fsWatcher.on("error", (error) => {
648
+ let message = error instanceof Error ? error.message : String(error);
649
+ console.warn(import_picocolors.default.yellow(`File watcher error: ${message}`));
651
650
  });
652
651
  fsWatcher.on("all", async (...args) => {
653
652
  let [event, rawFilepath] = args;
@@ -856,6 +855,25 @@ function isEntryFileDependency(moduleGraph, entryFilepath, filepath, visited = /
856
855
  }
857
856
  return false;
858
857
  }
858
+ function isIgnoredByWatcher(path10, { root, appDirectory }) {
859
+ let dirname4 = import_pathe3.default.dirname(path10);
860
+ let ignoredByPath = !dirname4.startsWith(appDirectory) && // Ensure we're only watching files outside of the app directory
861
+ // that are at the root level, not nested in subdirectories
862
+ path10 !== root && // Watch the root directory itself
863
+ dirname4 !== root;
864
+ if (ignoredByPath) {
865
+ return true;
866
+ }
867
+ try {
868
+ let stat = import_node_fs.default.statSync(path10, { throwIfNoEntry: false });
869
+ if (stat && !stat.isFile() && !stat.isDirectory()) {
870
+ return true;
871
+ }
872
+ } catch {
873
+ return true;
874
+ }
875
+ return false;
876
+ }
859
877
 
860
878
  // typegen/context.ts
861
879
  async function createContext2({
@@ -4523,15 +4541,17 @@ ${new TextDecoder().decode(contents)}`
4523
4541
  if (redirectStatusCodes.has(response.status)) {
4524
4542
  let location = response.headers.get("Location");
4525
4543
  let delay = response.status === 302 ? 2 : 0;
4544
+ let escapedLocation = escapeHtml(location ?? "");
4545
+ let escapedPathname = escapeHtml(pathname);
4526
4546
  html = `<!doctype html>
4527
4547
  <head>
4528
- <title>Redirecting to: ${location}</title>
4529
- <meta http-equiv="refresh" content="${delay};url=${location}">
4548
+ <title>Redirecting to: ${escapedLocation}</title>
4549
+ <meta http-equiv="refresh" content="${delay};url=${escapedLocation}">
4530
4550
  <meta name="robots" content="noindex">
4531
4551
  </head>
4532
4552
  <body>
4533
- <a href="${location}">
4534
- Redirecting from <code>${pathname}</code> to <code>${location}</code>
4553
+ <a href="${escapedLocation}">
4554
+ Redirecting from <code>${escapedPathname}</code> to <code>${escapedLocation}</code>
4535
4555
  </a>
4536
4556
  </body>
4537
4557
  </html>`;
@@ -4940,15 +4960,17 @@ async function prerenderRoute(handler, prerenderPath, clientBuildDirectory, reac
4940
4960
  if (redirectStatusCodes.has(response.status)) {
4941
4961
  let location = response.headers.get("Location");
4942
4962
  let delay = response.status === 302 ? 2 : 0;
4963
+ let escapedLocation = escapeHtml(location ?? "");
4964
+ let escapedNormalizedPath = escapeHtml(normalizedPath);
4943
4965
  html = `<!doctype html>
4944
4966
  <head>
4945
- <title>Redirecting to: ${location}</title>
4946
- <meta http-equiv="refresh" content="${delay};url=${location}">
4967
+ <title>Redirecting to: ${escapedLocation}</title>
4968
+ <meta http-equiv="refresh" content="${delay};url=${escapedLocation}">
4947
4969
  <meta name="robots" content="noindex">
4948
4970
  </head>
4949
4971
  <body>
4950
- <a href="${location}">
4951
- Redirecting from <code>${normalizedPath}</code> to <code>${location}</code>
4972
+ <a href="${escapedLocation}">
4973
+ Redirecting from <code>${escapedNormalizedPath}</code> to <code>${escapedLocation}</code>
4952
4974
  </a>
4953
4975
  </body>
4954
4976
  </html>`;
@@ -5590,6 +5612,17 @@ function createSpaModeRequest(reactRouterConfig) {
5590
5612
  metadata: { type: "spa", path: "/" }
5591
5613
  };
5592
5614
  }
5615
+ var ESCAPE_REGEX = /[&><\u2028\u2029]/g;
5616
+ var ESCAPE_LOOKUP = {
5617
+ "&": "\\u0026",
5618
+ ">": "\\u003e",
5619
+ "<": "\\u003c",
5620
+ "\u2028": "\\u2028",
5621
+ "\u2029": "\\u2029"
5622
+ };
5623
+ function escapeHtml(html) {
5624
+ return html.replace(ESCAPE_REGEX, (match) => ESCAPE_LOOKUP[match]);
5625
+ }
5593
5626
 
5594
5627
  // vite/rsc/plugin.ts
5595
5628
  var import_es_module_lexer3 = require("es-module-lexer");
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@c0va23/react-router-dev",
3
- "version": "7.13.1",
3
+ "version": "7.13.2",
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.13.1"
95
+ "@react-router/node": "7.13.2"
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": "^7.13.1",
120
- "@react-router/serve": "7.13.1"
119
+ "@react-router/serve": "7.13.2",
120
+ "react-router": "^7.13.2"
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": "^7.13.1",
129
- "@react-router/serve": "^7.13.1"
128
+ "@react-router/serve": "^7.13.2",
129
+ "react-router": "^7.13.2"
130
130
  },
131
131
  "peerDependenciesMeta": {
132
132
  "@vitejs/plugin-rsc": {