From eebd2e8e133c2ff3ada78706ffd2f2a9e6bae9dc Mon Sep 17 00:00:00 2001 From: Remix Run Bot Date: Wed, 24 Sep 2025 15:29:26 +0000 Subject: [PATCH 01/10] chore: format --- integration/CHANGELOG.md | 1 - packages/react-router-architect/CHANGELOG.md | 3 --- packages/react-router-cloudflare/CHANGELOG.md | 3 --- packages/react-router-dev/CHANGELOG.md | 8 -------- packages/react-router-express/CHANGELOG.md | 1 - packages/react-router-node/CHANGELOG.md | 5 ----- packages/react-router-serve/CHANGELOG.md | 2 -- packages/react-router/CHANGELOG.md | 10 +--------- 8 files changed, 1 insertion(+), 32 deletions(-) diff --git a/integration/CHANGELOG.md b/integration/CHANGELOG.md index 6fccf850d7..2cf67d87b7 100644 --- a/integration/CHANGELOG.md +++ b/integration/CHANGELOG.md @@ -5,7 +5,6 @@ ### Minor Changes - Unstable Vite support for Node-based Remix apps ([#7590](https://github.com/remix-run/remix/pull/7590)) - - `remix build` 👉 `vite build && vite build --ssr` - `remix dev` 👉 `vite dev` diff --git a/packages/react-router-architect/CHANGELOG.md b/packages/react-router-architect/CHANGELOG.md index 1da2b7124f..e014477037 100644 --- a/packages/react-router-architect/CHANGELOG.md +++ b/packages/react-router-architect/CHANGELOG.md @@ -23,7 +23,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -247,7 +246,6 @@ ### Major Changes - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) - - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -256,7 +254,6 @@ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: - - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` diff --git a/packages/react-router-cloudflare/CHANGELOG.md b/packages/react-router-cloudflare/CHANGELOG.md index 0c25a32490..f17a920747 100644 --- a/packages/react-router-cloudflare/CHANGELOG.md +++ b/packages/react-router-cloudflare/CHANGELOG.md @@ -21,7 +21,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -220,7 +219,6 @@ - For Remix consumers migrating to React Router, all exports from `@remix-run/cloudflare-pages` are now provided for React Router consumers in the `@react-router/cloudflare` package. There is no longer a separate package for Cloudflare Pages. ([#11801](https://github.com/remix-run/react-router/pull/11801)) - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) - - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -229,7 +227,6 @@ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: - - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` diff --git a/packages/react-router-dev/CHANGELOG.md b/packages/react-router-dev/CHANGELOG.md index 0b21ce1299..260463e646 100644 --- a/packages/react-router-dev/CHANGELOG.md +++ b/packages/react-router-dev/CHANGELOG.md @@ -36,7 +36,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -779,7 +778,6 @@ ``` This initial implementation targets type inference for: - - `Params` : Path parameters from your routing config in `routes.ts` including file-based routing - `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module - `ActionData` : Action data from `action` and/or `clientAction` within your route module @@ -794,7 +792,6 @@ ``` Check out our docs for more: - - [_Explanations > Type Safety_](https://reactrouter.com/dev/guides/explanation/type-safety) - [_How-To > Setting up type safety_](https://reactrouter.com/dev/guides/how-to/setting-up-type-safety) @@ -994,7 +991,6 @@ - Vite: Provide `Unstable_ServerBundlesFunction` and `Unstable_VitePluginConfig` types ([#8654](https://github.com/remix-run/remix/pull/8654)) - Vite: add `--sourcemapClient` and `--sourcemapServer` flags to `remix vite:build` ([#8613](https://github.com/remix-run/remix/pull/8613)) - - `--sourcemapClient` - `--sourcemapClient=inline` @@ -1331,7 +1327,6 @@ - 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)) 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: - - Leveraging a data source local to the browser (i.e., `localStorage`) - Managing a client-side cache of server data (like `IndexedDB`) - Bypassing the Remix server in a BFF setup and hitting your API directly from the browser @@ -1735,7 +1730,6 @@ - Output esbuild metafiles for bundle analysis ([#6772](https://github.com/remix-run/remix/pull/6772)) Written to server build directory (`build/` by default): - - `metafile.css.json` - `metafile.js.json` (browser JS) - `metafile.server.json` (server JS) @@ -1833,7 +1827,6 @@ - built-in tls support ([#6483](https://github.com/remix-run/remix/pull/6483)) New options: - - `--tls-key` / `tlsKey`: TLS key - `--tls-cert` / `tlsCert`: TLS Certificate @@ -2104,7 +2097,6 @@ ``` The dev server will: - - force `NODE_ENV=development` and warn you if it was previously set to something else - rebuild your app whenever your Remix app code changes - restart your app server whenever rebuilds succeed diff --git a/packages/react-router-express/CHANGELOG.md b/packages/react-router-express/CHANGELOG.md index 30d4c1b187..e58600466b 100644 --- a/packages/react-router-express/CHANGELOG.md +++ b/packages/react-router-express/CHANGELOG.md @@ -23,7 +23,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option diff --git a/packages/react-router-node/CHANGELOG.md b/packages/react-router-node/CHANGELOG.md index d492d812b7..c1e038fb65 100644 --- a/packages/react-router-node/CHANGELOG.md +++ b/packages/react-router-node/CHANGELOG.md @@ -21,7 +21,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -221,7 +220,6 @@ - Remove single fetch future flag. ([#11522](https://github.com/remix-run/react-router/pull/11522)) - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) - - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -230,7 +228,6 @@ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: - - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` @@ -638,12 +635,10 @@ - Introduces the `defer()` API from `@remix-run/router` with support for server-rendering and HTTP streaming. This utility allows you to defer values returned from `loader` functions by returning promises instead of resolved values. This has been refered to as _"sending a promise over the wire"_. ([#4920](https://github.com/remix-run/remix/pull/4920)) Informational Resources: - - - Documentation Resources (better docs specific to Remix are in the works): - - - - diff --git a/packages/react-router-serve/CHANGELOG.md b/packages/react-router-serve/CHANGELOG.md index a4614aefb8..b918937616 100644 --- a/packages/react-router-serve/CHANGELOG.md +++ b/packages/react-router-serve/CHANGELOG.md @@ -636,12 +636,10 @@ - Introduces the `defer()` API from `@remix-run/router` with support for server-rendering and HTTP streaming. This utility allows you to defer values returned from `loader` functions by returning promises instead of resolved values. This has been refered to as _"sending a promise over the wire"_. ([#4920](https://github.com/remix-run/remix/pull/4920)) Informational Resources: - - - Documentation Resources (better docs specific to Remix are in the works): - - - - diff --git a/packages/react-router/CHANGELOG.md b/packages/react-router/CHANGELOG.md index 6c39008486..e164dc1201 100644 --- a/packages/react-router/CHANGELOG.md +++ b/packages/react-router/CHANGELOG.md @@ -39,7 +39,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -66,7 +65,7 @@ - \[UNSTABLE] Add ``/`` prop for client side error reporting ([#14162](https://github.com/remix-run/react-router/pull/14162)) -- server action revalidation opt out via $SKIP\_REVALIDATION field ([#14154](https://github.com/remix-run/react-router/pull/14154)) +- server action revalidation opt out via $SKIP_REVALIDATION field ([#14154](https://github.com/remix-run/react-router/pull/14154)) - Properly escape interpolated param values in `generatePath()` ([#13530](https://github.com/remix-run/react-router/pull/13530)) @@ -115,7 +114,6 @@ - Remove dependency on `@types/node` in TypeScript declaration files ([#14059](https://github.com/remix-run/react-router/pull/14059)) - Fix types for `UIMatch` to reflect that the `loaderData`/`data` properties may be `undefined` ([#12206](https://github.com/remix-run/react-router/pull/12206)) - - When an `ErrorBoundary` is being rendered, not all active matches will have loader data available, since it may have been their `loader` that threw to trigger the boundary - The `UIMatch.data` type was not correctly handing this and would always reflect the presence of data, leading to the unexpected runtime errors when an `ErrorBoundary` was rendered - ⚠️ This may cause some type errors to show up in your code for unguarded `match.data` accesses - you should properly guard for `undefined` values in those scenarios. @@ -149,7 +147,6 @@ - \[UNSTABLE] When middleware is enabled, make the `context` parameter read-only (via `Readonly`) so that TypeScript will not allow you to write arbitrary fields to it in loaders, actions, or middleware. ([#14097](https://github.com/remix-run/react-router/pull/14097)) - \[UNSTABLE] Rename and alter the signature/functionality of the `unstable_respond` API in `staticHandler.query`/`staticHandler.queryRoute` ([#14103](https://github.com/remix-run/react-router/pull/14103)) - - The API has been renamed to `unstable_generateMiddlewareResponse` for clarity - The main functional change is that instead of running the loaders/actions before calling `unstable_respond` and handing you the result, we now pass a `query`/`queryRoute` function as a parameter and you execute the loaders/actions inside your callback, giving you full access to pre-processing and error handling - The `query` version of the API now has a signature of `(query: (r: Request) => Promise) => Promise` @@ -795,7 +792,6 @@ ``` Similar to server-side requests, a fresh `context` will be created per navigation (or `fetcher` call). If you have initial data you'd like to populate in the context for every request, you can provide an `unstable_getContext` function at the root of your app: - - Library mode - `createBrowserRouter(routes, { unstable_getContext })` - Framework mode - `` @@ -983,7 +979,6 @@ _No changes_ - Remove `future.v7_normalizeFormMethod` future flag ([#11697](https://github.com/remix-run/react-router/pull/11697)) - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) - - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -992,7 +987,6 @@ _No changes_ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: - - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` @@ -1148,7 +1142,6 @@ _No changes_ ``` This initial implementation targets type inference for: - - `Params` : Path parameters from your routing config in `routes.ts` including file-based routing - `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module - `ActionData` : Action data from `action` and/or `clientAction` within your route module @@ -1163,7 +1156,6 @@ _No changes_ ``` Check out our docs for more: - - [_Explanations > Type Safety_](https://reactrouter.com/dev/guides/explanation/type-safety) - [_How-To > Setting up type safety_](https://reactrouter.com/dev/guides/how-to/setting-up-type-safety) From eb61a296b82d192e3ac3e66af002a497c924ffa9 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Wed, 24 Sep 2025 14:20:50 -0400 Subject: [PATCH 02/10] Avoid decoding CDN errors that never reached the origin server (#14385) --- .changeset/happy-hornets-judge.md | 7 +++++++ integration/error-boundary-v2-test.ts | 4 ++-- integration/error-data-request-test.ts | 6 +++--- .../__tests__/server-runtime/server-test.ts | 16 +++++++--------- .../react-router/lib/dom/ssr/single-fetch.tsx | 12 ++++++++---- packages/react-router/lib/rsc/browser.tsx | 12 ++++++++---- packages/react-router/lib/rsc/server.rsc.ts | 4 ++-- packages/react-router/lib/rsc/server.ssr.tsx | 2 +- .../react-router/lib/server-runtime/server.ts | 6 ------ 9 files changed, 38 insertions(+), 31 deletions(-) create mode 100644 .changeset/happy-hornets-judge.md diff --git a/.changeset/happy-hornets-judge.md b/.changeset/happy-hornets-judge.md new file mode 100644 index 0000000000..bb336a6b07 --- /dev/null +++ b/.changeset/happy-hornets-judge.md @@ -0,0 +1,7 @@ +--- +"react-router": patch +--- + +Do not try to use `turbo-stream` to decode CDN errors that never reached the server + +- We used to do this but lost this check with the adoption of single fetch diff --git a/integration/error-boundary-v2-test.ts b/integration/error-boundary-v2-test.ts index 32602e10a6..87d0fcbdfc 100644 --- a/integration/error-boundary-v2-test.ts +++ b/integration/error-boundary-v2-test.ts @@ -177,8 +177,8 @@ test.describe("ErrorBoundary", () => { await waitForAndAssert( page, app, - "#parent-error", - "Unable to decode turbo-stream response", + "#parent-error-response", + "500 CDN Error!", ); }); }); diff --git a/integration/error-data-request-test.ts b/integration/error-data-request-test.ts index 772ef8af57..187ac67273 100644 --- a/integration/error-data-request-test.ts +++ b/integration/error-data-request-test.ts @@ -110,7 +110,7 @@ test.describe("ErrorBoundary", () => { let { status, headers, data } = await fixture.requestSingleFetchData("/_root.data"); expect(status).toBe(200); - expect(headers.has("X-Remix-Error")).toBe(false); + expect(headers.has("X-Remix-Response")).toBe(true); expect(data).toEqual({}); }); @@ -122,7 +122,7 @@ test.describe("ErrorBoundary", () => { }, ); expect(status).toBe(405); - expect(headers.has("X-Remix-Error")).toBe(false); + expect(headers.has("X-Remix-Response")).toBe(true); expect(data).toEqual({ error: new ErrorResponseImpl( 405, @@ -153,7 +153,7 @@ test.describe("ErrorBoundary", () => { "/i/match/nothing.data", ); expect(status).toBe(404); - expect(headers.has("X-Remix-Error")).toBe(false); + expect(headers.has("X-Remix-Response")).toBe(true); expect(data).toEqual({ root: { error: new ErrorResponseImpl( diff --git a/packages/react-router/__tests__/server-runtime/server-test.ts b/packages/react-router/__tests__/server-runtime/server-test.ts index 69ab365b3a..725c49792e 100644 --- a/packages/react-router/__tests__/server-runtime/server-test.ts +++ b/packages/react-router/__tests__/server-runtime/server-test.ts @@ -555,7 +555,7 @@ describe("shared server runtime", () => { let result = await handler(request); expect(result.status).toBe(400); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); + expect(headers.has("X-Remix-Response")).toBe(true); expect((await result.json()).message).toBeTruthy(); }); @@ -585,7 +585,7 @@ describe("shared server runtime", () => { let result = await handler(request); expect(result.status).toBe(403); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); + expect(headers.has("X-Remix-Response")).toBe(true); expect((await result.json()).message).toBeTruthy(); }); @@ -608,7 +608,7 @@ describe("shared server runtime", () => { let result = await handler(request); expect(result.status).toBe(404); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); + expect(headers.has("X-Remix-Response")).toBe(true); expect((await result.json()).message).toBeTruthy(); }); @@ -670,7 +670,7 @@ describe("shared server runtime", () => { let result = await handler(request); expect(result.status).toBe(500); expect((await result.json()).message).toBe("Unexpected Server Error"); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); + expect(headers.has("X-Remix-Response")).toBe(true); expect(rootLoader.mock.calls.length).toBe(1); expect(testAction.mock.calls.length).toBe(0); }); @@ -704,7 +704,7 @@ describe("shared server runtime", () => { let result = await handler(request); expect(result.status).toBe(500); expect((await result.json()).message).toBe(message); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); + expect(headers.has("X-Remix-Response")).toBe(true); expect(rootLoader.mock.calls.length).toBe(1); expect(testAction.mock.calls.length).toBe(0); expect(spy.console.mock.calls.length).toBe(1); @@ -737,7 +737,6 @@ describe("shared server runtime", () => { let result = await handler(request); expect(result.status).toBe(400); expect(await result.text()).toBe("test"); - expect(result.headers.get("X-Remix-Catch")).toBe("yes"); expect(rootLoader.mock.calls.length).toBe(1); expect(testAction.mock.calls.length).toBe(0); }); @@ -800,7 +799,7 @@ describe("shared server runtime", () => { let result = await handler(request); expect(result.status).toBe(500); expect((await result.json()).message).toBe("Unexpected Server Error"); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); + expect(headers.has("X-Remix-Response")).toBe(true); expect(rootLoader.mock.calls.length).toBe(0); expect(testAction.mock.calls.length).toBe(1); }); @@ -834,7 +833,7 @@ describe("shared server runtime", () => { let result = await handler(request); expect(result.status).toBe(500); expect((await result.json()).message).toBe(message); - expect(result.headers.get("X-Remix-Error")).toBe("yes"); + expect(headers.has("X-Remix-Response")).toBe(true); expect(rootLoader.mock.calls.length).toBe(0); expect(testAction.mock.calls.length).toBe(1); expect(spy.console.mock.calls.length).toBe(1); @@ -867,7 +866,6 @@ describe("shared server runtime", () => { let result = await handler(request); expect(result.status).toBe(400); expect(await result.text()).toBe("test"); - expect(result.headers.get("X-Remix-Catch")).toBe("yes"); expect(rootLoader.mock.calls.length).toBe(0); expect(testAction.mock.calls.length).toBe(1); }); diff --git a/packages/react-router/lib/dom/ssr/single-fetch.tsx b/packages/react-router/lib/dom/ssr/single-fetch.tsx index 4043e35c46..bffc02708d 100644 --- a/packages/react-router/lib/dom/ssr/single-fetch.tsx +++ b/packages/react-router/lib/dom/ssr/single-fetch.tsx @@ -610,10 +610,14 @@ async function fetchAndDecodeViaTurboStream( let res = await fetch(url, await createRequestInit(request)); - // If this 404'd without hitting the running server (most likely in a - // pre-rendered app using a CDN), then bubble a standard 404 ErrorResponse - if (res.status === 404 && !res.headers.has("X-Remix-Response")) { - throw new ErrorResponseImpl(404, "Not Found", true); + // If this error'd without hitting the running server, then bubble a normal + // `ErrorResponse` and don't try to decode the body with `turbo-stream`. + // + // This could be triggered by a few scenarios: + // - `.data` request 404 on a pre-rendered app using a CDN + // - 429 error returned from a CDN on a SSR app + if (res.status >= 400 && !res.headers.has("X-Remix-Response")) { + throw new ErrorResponseImpl(res.status, res.statusText, await res.text()); } // Handle non-RR redirects (i.e., from express middleware) diff --git a/packages/react-router/lib/rsc/browser.tsx b/packages/react-router/lib/rsc/browser.tsx index 762773c639..9b9974bc70 100644 --- a/packages/react-router/lib/rsc/browser.tsx +++ b/packages/react-router/lib/rsc/browser.tsx @@ -530,10 +530,14 @@ function getFetchAndDecodeViaRSC( new Request(url, await createRequestInit(request)), ); - // If this 404'd without hitting the running server (most likely in a - // pre-rendered app using a CDN), then bubble a standard 404 ErrorResponse - if (res.status === 404 && !res.headers.has("X-Remix-Response")) { - throw new ErrorResponseImpl(404, "Not Found", true); + // If this error'd without hitting the running server, then bubble a normal + // `ErrorResponse` and don't try to decode the body with `turbo-stream`. + // + // This could be triggered by a few scenarios: + // - `.data` request 404 on a pre-rendered app using a CDN + // - 429 error returned from a CDN on a SSR app + if (res.status >= 400 && !res.headers.has("X-Remix-Response")) { + throw new ErrorResponseImpl(res.status, res.statusText, await res.text()); } invariant(res.body, "No response body to decode"); diff --git a/packages/react-router/lib/rsc/server.rsc.ts b/packages/react-router/lib/rsc/server.rsc.ts index d8880506ac..c911c7641a 100644 --- a/packages/react-router/lib/rsc/server.rsc.ts +++ b/packages/react-router/lib/rsc/server.rsc.ts @@ -455,8 +455,8 @@ export async function matchRSCServerRequest({ generateResponse, temporaryReferences, ); - // The front end uses this to know whether a 404 status came from app code - // or 404'd and never reached the origin server + // The front end uses this to know whether a 4xx/5xx status came from app code + // or never reached the origin server response.headers.set("X-Remix-Response", "yes"); return response; } diff --git a/packages/react-router/lib/rsc/server.ssr.tsx b/packages/react-router/lib/rsc/server.ssr.tsx index 7eeb8a91f6..7662d29947 100644 --- a/packages/react-router/lib/rsc/server.ssr.tsx +++ b/packages/react-router/lib/rsc/server.ssr.tsx @@ -196,7 +196,7 @@ export async function routeRSCServerRequest({ headers.delete("Content-Encoding"); headers.delete("Content-Length"); headers.delete("Content-Type"); - headers.delete("x-remix-response"); + headers.delete("X-Remix-Response"); headers.set("Location", payload.location); return new Response(serverResponseB?.body || "", { diff --git a/packages/react-router/lib/server-runtime/server.ts b/packages/react-router/lib/server-runtime/server.ts index d3b78ae510..71f4d11b04 100644 --- a/packages/react-router/lib/server-runtime/server.ts +++ b/packages/react-router/lib/server-runtime/server.ts @@ -661,9 +661,6 @@ async function handleResourceRequest( function handleQueryRouteError(error: unknown) { if (isResponse(error)) { - // Note: Not functionally required but ensures that our response headers - // match identically to what Remix returns - error.headers.set("X-Remix-Catch", "yes"); return error; } @@ -701,9 +698,6 @@ function errorResponseToJson( { status: errorResponse.status, statusText: errorResponse.statusText, - headers: { - "X-Remix-Error": "yes", - }, }, ); } From 01243a200d0df62e950eb260b39c118e1bf39833 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Fri, 26 Sep 2025 14:18:12 -0400 Subject: [PATCH 03/10] Fix middleware on initial load without loaders (#14393) --- .changeset/twelve-dogs-pump.md | 5 ++ .../router/context-middleware-test.tsx | 56 +++++++++++++++++++ packages/react-router/lib/router/router.ts | 15 ++++- 3 files changed, 73 insertions(+), 3 deletions(-) create mode 100644 .changeset/twelve-dogs-pump.md diff --git a/.changeset/twelve-dogs-pump.md b/.changeset/twelve-dogs-pump.md new file mode 100644 index 0000000000..d61525d917 --- /dev/null +++ b/.changeset/twelve-dogs-pump.md @@ -0,0 +1,5 @@ +--- +"react-router": patch +--- + +Fix Data Mode regression causing a 404 during initial load in when `middleware` exists without any `loader` functions diff --git a/packages/react-router/__tests__/router/context-middleware-test.tsx b/packages/react-router/__tests__/router/context-middleware-test.tsx index 9db190d373..cea82e235c 100644 --- a/packages/react-router/__tests__/router/context-middleware-test.tsx +++ b/packages/react-router/__tests__/router/context-middleware-test.tsx @@ -300,6 +300,62 @@ describe("context/middleware", () => { ]); }); + it("runs middleware on initialization even if no loaders exist", async () => { + let snapshot; + router = createRouter({ + history: createMemoryHistory(), + routes: [ + { + path: "/", + middleware: [ + async ({ context }, next) => { + await next(); + // Grab a snapshot at the end of the upwards middleware chain + snapshot = context.get(orderContext); + }, + getOrderMiddleware(orderContext, "a"), + getOrderMiddleware(orderContext, "b"), + ], + children: [ + { + index: true, + middleware: [ + getOrderMiddleware(orderContext, "c"), + getOrderMiddleware(orderContext, "d"), + ], + }, + ], + }, + ], + }); + let initPromise = new Promise((r) => { + let unsub = router.subscribe((state) => { + if (state.initialized) { + unsub(); + r(undefined); + } + }); + }); + await router.initialize(); + await initPromise; + expect(router.state).toMatchObject({ + initialized: true, + location: { pathname: "/" }, + navigation: { state: "idle" }, + errors: null, + }); + expect(snapshot).toEqual([ + "a middleware - before next()", + "b middleware - before next()", + "c middleware - before next()", + "d middleware - before next()", + "d middleware - after next()", + "c middleware - after next()", + "b middleware - after next()", + "a middleware - after next()", + ]); + }); + it("runs middleware even if no loaders exist", async () => { let snapshot; router = createRouter({ diff --git a/packages/react-router/lib/router/router.ts b/packages/react-router/lib/router/router.ts index 2c3e379345..4cd9d1df51 100644 --- a/packages/react-router/lib/router/router.ts +++ b/packages/react-router/lib/router/router.ts @@ -5744,13 +5744,22 @@ function getDataStrategyMatch( return shouldRevalidateLoader(match, unstable_shouldRevalidateArgs); }, resolve(handlerOverride) { - if ( + let { lazy, loader, middleware } = match.route; + + let callHandler = isUsingNewApi || shouldLoad || (handlerOverride && !isMutationMethod(request.method) && - (match.route.lazy || match.route.loader)) - ) { + (lazy || loader)); + + // If this match was marked `shouldLoad` due to a middleware and it + // doesn't have a `loader` to run and no `lazy` to add one, then we can + // just return undefined from the "loader" here + let isMiddlewareOnlyRoute = + middleware && middleware.length > 0 && !loader && !lazy; + + if (callHandler && !isMiddlewareOnlyRoute) { return callLoaderOrAction({ request, match, From 4a3b6f263719081917594dab5f47b8d12ccf1678 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Fri, 26 Sep 2025 14:18:28 -0400 Subject: [PATCH 04/10] Enter prerelease mode --- .changeset/pre.json | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 .changeset/pre.json diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 0000000000..76eee9a8bf --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,40 @@ +{ + "mode": "pre", + "tag": "pre", + "initialVersions": { + "integration": "0.0.0", + "integration-cloudflare-dev-proxy-template": "0.0.0", + "integration-rsc-parcel": "0.0.0", + "integration-rsc-vite": "0.0.0", + "integration-rsc-vite-framework": "0.0.0", + "integration-vite-5-template": "0.0.0", + "integration-vite-6-template": "0.0.0", + "integration-vite-7-beta-template": "0.0.0", + "integration-vite-plugin-cloudflare-template": "0.0.0", + "integration-vite-rolldown-template": "0.0.0", + "create-react-router": "7.9.2", + "react-router": "7.9.2", + "@react-router/architect": "7.9.2", + "@react-router/cloudflare": "7.9.2", + "@react-router/dev": "7.9.2", + "react-router-dom": "7.9.2", + "@react-router/express": "7.9.2", + "@react-router/fs-routes": "7.9.2", + "@react-router/node": "7.9.2", + "@react-router/remix-routes-option-adapter": "7.9.2", + "@react-router/serve": "7.9.2", + "@playground/framework": "0.0.0", + "@playground/framework-express": "0.0.0", + "@playground/framework-rolldown-vite": "0.0.0", + "@playground/framework-spa": "0.0.0", + "@playground/framework-vite-5": "0.0.0", + "@playground/framework-vite-7-beta": "0.0.0", + "@playground/rsc-parcel": "0.0.0", + "@playground/rsc-vite": "0.0.0", + "@playground/rsc-vite-framework": "0.0.0", + "@playground/split-route-modules": "0.0.0", + "@playground/split-route-modules-spa": "0.0.0", + "@playground/vite-plugin-cloudflare": "0.0.0" + }, + "changesets": [] +} From b6c49ecb0a6a057fbdba0ecdf7e6e6fbc56911e4 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 14:21:35 -0400 Subject: [PATCH 05/10] chore: Update version for release (pre) (#14394) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/pre.json | 5 ++++- packages/create-react-router/CHANGELOG.md | 2 ++ packages/create-react-router/package.json | 2 +- packages/react-router-architect/CHANGELOG.md | 8 ++++++++ packages/react-router-architect/package.json | 2 +- packages/react-router-cloudflare/CHANGELOG.md | 7 +++++++ packages/react-router-cloudflare/package.json | 2 +- packages/react-router-dev/CHANGELOG.md | 9 +++++++++ packages/react-router-dev/package.json | 2 +- packages/react-router-dom/CHANGELOG.md | 7 +++++++ packages/react-router-dom/package.json | 2 +- packages/react-router-express/CHANGELOG.md | 8 ++++++++ packages/react-router-express/package.json | 2 +- packages/react-router-fs-routes/CHANGELOG.md | 7 +++++++ packages/react-router-fs-routes/package.json | 2 +- packages/react-router-node/CHANGELOG.md | 7 +++++++ packages/react-router-node/package.json | 2 +- .../CHANGELOG.md | 7 +++++++ .../package.json | 2 +- packages/react-router-serve/CHANGELOG.md | 9 +++++++++ packages/react-router-serve/package.json | 2 +- packages/react-router/CHANGELOG.md | 9 +++++++++ packages/react-router/package.json | 2 +- 23 files changed, 95 insertions(+), 12 deletions(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 76eee9a8bf..09a02c7bce 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -36,5 +36,8 @@ "@playground/split-route-modules-spa": "0.0.0", "@playground/vite-plugin-cloudflare": "0.0.0" }, - "changesets": [] + "changesets": [ + "happy-hornets-judge", + "twelve-dogs-pump" + ] } diff --git a/packages/create-react-router/CHANGELOG.md b/packages/create-react-router/CHANGELOG.md index 46248d8c92..16eaa1cf95 100644 --- a/packages/create-react-router/CHANGELOG.md +++ b/packages/create-react-router/CHANGELOG.md @@ -1,5 +1,7 @@ # `create-react-router` +## 7.9.3-pre.0 + ## 7.9.2 _No changes_ diff --git a/packages/create-react-router/package.json b/packages/create-react-router/package.json index a5ad8e609f..f398e07216 100644 --- a/packages/create-react-router/package.json +++ b/packages/create-react-router/package.json @@ -1,6 +1,6 @@ { "name": "create-react-router", - "version": "7.9.2", + "version": "7.9.3-pre.0", "description": "Create a new React Router app", "homepage": "https://reactrouter.com", "bugs": { diff --git a/packages/react-router-architect/CHANGELOG.md b/packages/react-router-architect/CHANGELOG.md index e014477037..215666cfd3 100644 --- a/packages/react-router-architect/CHANGELOG.md +++ b/packages/react-router-architect/CHANGELOG.md @@ -1,5 +1,13 @@ # `@react-router/architect` +## 7.9.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `react-router@7.9.3-pre.0` + - `@react-router/node@7.9.3-pre.0` + ## 7.9.2 ### Patch Changes diff --git a/packages/react-router-architect/package.json b/packages/react-router-architect/package.json index 9e7c2c1110..ad5b9504dd 100644 --- a/packages/react-router-architect/package.json +++ b/packages/react-router-architect/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/architect", - "version": "7.9.2", + "version": "7.9.3-pre.0", "description": "Architect server request handler for React Router", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-cloudflare/CHANGELOG.md b/packages/react-router-cloudflare/CHANGELOG.md index f17a920747..5a2bb296b1 100644 --- a/packages/react-router-cloudflare/CHANGELOG.md +++ b/packages/react-router-cloudflare/CHANGELOG.md @@ -1,5 +1,12 @@ # `@react-router/cloudflare` +## 7.9.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `react-router@7.9.3-pre.0` + ## 7.9.2 ### Patch Changes diff --git a/packages/react-router-cloudflare/package.json b/packages/react-router-cloudflare/package.json index 9897f57dd9..44626ea7b6 100644 --- a/packages/react-router-cloudflare/package.json +++ b/packages/react-router-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/cloudflare", - "version": "7.9.2", + "version": "7.9.3-pre.0", "description": "Cloudflare platform abstractions for React Router", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-dev/CHANGELOG.md b/packages/react-router-dev/CHANGELOG.md index 260463e646..200adcdab4 100644 --- a/packages/react-router-dev/CHANGELOG.md +++ b/packages/react-router-dev/CHANGELOG.md @@ -1,5 +1,14 @@ # `@react-router/dev` +## 7.9.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `react-router@7.9.3-pre.0` + - `@react-router/node@7.9.3-pre.0` + - `@react-router/serve@7.9.3-pre.0` + ## 7.9.2 ### Patch Changes diff --git a/packages/react-router-dev/package.json b/packages/react-router-dev/package.json index 114f9c9f36..8284f7f433 100644 --- a/packages/react-router-dev/package.json +++ b/packages/react-router-dev/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/dev", - "version": "7.9.2", + "version": "7.9.3-pre.0", "description": "Dev tools and CLI for React Router", "homepage": "https://reactrouter.com", "bugs": { diff --git a/packages/react-router-dom/CHANGELOG.md b/packages/react-router-dom/CHANGELOG.md index eb67840d0a..d5b0728090 100644 --- a/packages/react-router-dom/CHANGELOG.md +++ b/packages/react-router-dom/CHANGELOG.md @@ -1,5 +1,12 @@ # react-router-dom +## 7.9.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `react-router@7.9.3-pre.0` + ## 7.9.2 ### Patch Changes diff --git a/packages/react-router-dom/package.json b/packages/react-router-dom/package.json index a2061889b7..0a7f320ded 100644 --- a/packages/react-router-dom/package.json +++ b/packages/react-router-dom/package.json @@ -1,6 +1,6 @@ { "name": "react-router-dom", - "version": "7.9.2", + "version": "7.9.3-pre.0", "description": "Declarative routing for React web applications", "keywords": [ "react", diff --git a/packages/react-router-express/CHANGELOG.md b/packages/react-router-express/CHANGELOG.md index e58600466b..dc425040d2 100644 --- a/packages/react-router-express/CHANGELOG.md +++ b/packages/react-router-express/CHANGELOG.md @@ -1,5 +1,13 @@ # `@react-router/express` +## 7.9.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `react-router@7.9.3-pre.0` + - `@react-router/node@7.9.3-pre.0` + ## 7.9.2 ### Patch Changes diff --git a/packages/react-router-express/package.json b/packages/react-router-express/package.json index 3ffab6f810..b8f3bff83a 100644 --- a/packages/react-router-express/package.json +++ b/packages/react-router-express/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/express", - "version": "7.9.2", + "version": "7.9.3-pre.0", "description": "Express server request handler for React Router", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-fs-routes/CHANGELOG.md b/packages/react-router-fs-routes/CHANGELOG.md index 0336b8a6d8..ba2642580e 100644 --- a/packages/react-router-fs-routes/CHANGELOG.md +++ b/packages/react-router-fs-routes/CHANGELOG.md @@ -1,5 +1,12 @@ # `@react-router/fs-routes` +## 7.9.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@react-router/dev@7.9.3-pre.0` + ## 7.9.2 ### Patch Changes diff --git a/packages/react-router-fs-routes/package.json b/packages/react-router-fs-routes/package.json index 6a74cf9feb..b75ff9cb13 100644 --- a/packages/react-router-fs-routes/package.json +++ b/packages/react-router-fs-routes/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/fs-routes", - "version": "7.9.2", + "version": "7.9.3-pre.0", "description": "File system routing conventions for React Router, for use within routes.ts", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-node/CHANGELOG.md b/packages/react-router-node/CHANGELOG.md index c1e038fb65..1537ba9c60 100644 --- a/packages/react-router-node/CHANGELOG.md +++ b/packages/react-router-node/CHANGELOG.md @@ -1,5 +1,12 @@ # `@react-router/node` +## 7.9.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `react-router@7.9.3-pre.0` + ## 7.9.2 ### Patch Changes diff --git a/packages/react-router-node/package.json b/packages/react-router-node/package.json index 296b51be4f..d7019d9e2d 100644 --- a/packages/react-router-node/package.json +++ b/packages/react-router-node/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/node", - "version": "7.9.2", + "version": "7.9.3-pre.0", "description": "Node.js platform abstractions for React Router", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-remix-routes-option-adapter/CHANGELOG.md b/packages/react-router-remix-routes-option-adapter/CHANGELOG.md index 8ec81f0cf2..54e96e0020 100644 --- a/packages/react-router-remix-routes-option-adapter/CHANGELOG.md +++ b/packages/react-router-remix-routes-option-adapter/CHANGELOG.md @@ -1,5 +1,12 @@ # `@react-router/remix-config-routes-adapter` +## 7.9.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `@react-router/dev@7.9.3-pre.0` + ## 7.9.2 ### Patch Changes diff --git a/packages/react-router-remix-routes-option-adapter/package.json b/packages/react-router-remix-routes-option-adapter/package.json index c38f0963a9..f2cc6e4094 100644 --- a/packages/react-router-remix-routes-option-adapter/package.json +++ b/packages/react-router-remix-routes-option-adapter/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/remix-routes-option-adapter", - "version": "7.9.2", + "version": "7.9.3-pre.0", "description": "Adapter for Remix's \"routes\" config option, for use within routes.ts", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-serve/CHANGELOG.md b/packages/react-router-serve/CHANGELOG.md index b918937616..6a1e5aea06 100644 --- a/packages/react-router-serve/CHANGELOG.md +++ b/packages/react-router-serve/CHANGELOG.md @@ -1,5 +1,14 @@ # `@react-router/serve` +## 7.9.3-pre.0 + +### Patch Changes + +- Updated dependencies: + - `react-router@7.9.3-pre.0` + - `@react-router/node@7.9.3-pre.0` + - `@react-router/express@7.9.3-pre.0` + ## 7.9.2 ### Patch Changes diff --git a/packages/react-router-serve/package.json b/packages/react-router-serve/package.json index 42c995a848..e3776299ae 100644 --- a/packages/react-router-serve/package.json +++ b/packages/react-router-serve/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/serve", - "version": "7.9.2", + "version": "7.9.3-pre.0", "description": "Production application server for React Router", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router/CHANGELOG.md b/packages/react-router/CHANGELOG.md index e164dc1201..7fbd81f324 100644 --- a/packages/react-router/CHANGELOG.md +++ b/packages/react-router/CHANGELOG.md @@ -1,5 +1,14 @@ # `react-router` +## 7.9.3-pre.0 + +### Patch Changes + +- Do not try to use `turbo-stream` to decode CDN errors that never reached the server ([#14385](https://github.com/remix-run/react-router/pull/14385)) + - We used to do this but lost this check with the adoption of single fetch + +- Fix Data Mode regression causing a 404 during initial load in when `middleware` exists without any `loader` functions ([#14393](https://github.com/remix-run/react-router/pull/14393)) + ## 7.9.2 ### Patch Changes diff --git a/packages/react-router/package.json b/packages/react-router/package.json index 59376903f1..471596b12b 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -1,6 +1,6 @@ { "name": "react-router", - "version": "7.9.2", + "version": "7.9.3-pre.0", "description": "Declarative routing for React", "keywords": [ "react", From 14abb0783da821f2ec0d6578b7b56c995c4a7e5c Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Fri, 26 Sep 2025 14:25:12 -0400 Subject: [PATCH 06/10] Draft release notes --- CHANGELOG.md | 197 +++++++++++++++++++++++++++------------------------ 1 file changed, 106 insertions(+), 91 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 458e0446f9..a2a1a00b55 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,86 +13,88 @@ We manage release notes in this file instead of the paginated Github Releases Pa Table of Contents - [React Router Releases](#react-router-releases) + - [v7.9.3](#v793) + - [Patch Changes](#patch-changes) - [v7.9.2](#v792) - [What's Changed](#whats-changed) - [RSC Framework Mode (unstable)](#rsc-framework-mode-unstable) - [Fetcher Reset (unstable)](#fetcher-reset-unstable) - - [Patch Changes](#patch-changes) + - [Patch Changes](#patch-changes-1) - [Unstable Changes](#unstable-changes) - [v7.9.1](#v791) - - [Patch Changes](#patch-changes-1) + - [Patch Changes](#patch-changes-2) - [v7.9.0](#v790) - [What's Changed](#whats-changed-1) - [Stable Middleware and Context APIs](#stable-middleware-and-context-apis) - [Minor Changes](#minor-changes) - - [Patch Changes](#patch-changes-2) + - [Patch Changes](#patch-changes-3) - [Unstable Changes](#unstable-changes-1) - [v7.8.2](#v782) - - [Patch Changes](#patch-changes-3) + - [Patch Changes](#patch-changes-4) - [Unstable Changes](#unstable-changes-2) - [v7.8.1](#v781) - - [Patch Changes](#patch-changes-4) + - [Patch Changes](#patch-changes-5) - [Unstable Changes](#unstable-changes-3) - [v7.8.0](#v780) - [What's Changed](#whats-changed-2) - [Consistently named `loaderData` values](#consistently-named-loaderdata-values) - [Improvements/fixes to the middleware APIs (unstable)](#improvementsfixes-to-the-middleware-apis-unstable) - [Minor Changes](#minor-changes-1) - - [Patch Changes](#patch-changes-5) + - [Patch Changes](#patch-changes-6) - [Unstable Changes](#unstable-changes-4) - [Changes by Package](#changes-by-package) - [v7.7.1](#v771) - - [Patch Changes](#patch-changes-6) + - [Patch Changes](#patch-changes-7) - [Unstable Changes](#unstable-changes-5) - [v7.7.0](#v770) - [What's Changed](#whats-changed-3) - [Unstable RSC APIs](#unstable-rsc-apis) - [Minor Changes](#minor-changes-2) - - [Patch Changes](#patch-changes-7) + - [Patch Changes](#patch-changes-8) - [Unstable Changes](#unstable-changes-6) - [Changes by Package](#changes-by-package-1) - [v7.6.3](#v763) - - [Patch Changes](#patch-changes-8) - - [v7.6.2](#v762) - [Patch Changes](#patch-changes-9) - - [v7.6.1](#v761) + - [v7.6.2](#v762) - [Patch Changes](#patch-changes-10) + - [v7.6.1](#v761) + - [Patch Changes](#patch-changes-11) - [Unstable Changes](#unstable-changes-7) - [v7.6.0](#v760) - [What's Changed](#whats-changed-4) - [`routeDiscovery` Config Option](#routediscovery-config-option) - [Automatic Types for Future Flags](#automatic-types-for-future-flags) - [Minor Changes](#minor-changes-3) - - [Patch Changes](#patch-changes-11) + - [Patch Changes](#patch-changes-12) - [Unstable Changes](#unstable-changes-8) - [Changes by Package](#changes-by-package-2) - [v7.5.3](#v753) - - [Patch Changes](#patch-changes-12) + - [Patch Changes](#patch-changes-13) - [v7.5.2](#v752) - [Security Notice](#security-notice) - - [Patch Changes](#patch-changes-13) - - [v7.5.1](#v751) - [Patch Changes](#patch-changes-14) + - [v7.5.1](#v751) + - [Patch Changes](#patch-changes-15) - [Unstable Changes](#unstable-changes-9) - [v7.5.0](#v750) - [What's Changed](#whats-changed-5) - [`route.lazy` Object API](#routelazy-object-api) - [Minor Changes](#minor-changes-4) - - [Patch Changes](#patch-changes-15) + - [Patch Changes](#patch-changes-16) - [Unstable Changes](#unstable-changes-10) - [Changes by Package](#changes-by-package-3) - [v7.4.1](#v741) - [Security Notice](#security-notice-1) - - [Patch Changes](#patch-changes-16) + - [Patch Changes](#patch-changes-17) - [Unstable Changes](#unstable-changes-11) - [v7.4.0](#v740) - [Minor Changes](#minor-changes-5) - - [Patch Changes](#patch-changes-17) + - [Patch Changes](#patch-changes-18) - [Unstable Changes](#unstable-changes-12) - [Changes by Package](#changes-by-package-4) - [v7.3.0](#v730) - [Minor Changes](#minor-changes-6) - - [Patch Changes](#patch-changes-18) + - [Patch Changes](#patch-changes-19) - [Unstable Changes](#unstable-changes-13) - [Client-side `context` (unstable)](#client-side-context-unstable) - [Middleware (unstable)](#middleware-unstable) @@ -105,28 +107,28 @@ We manage release notes in this file instead of the paginated Github Releases Pa - [Prerendering with a SPA Fallback](#prerendering-with-a-spa-fallback) - [Allow a root `loader` in SPA Mode](#allow-a-root-loader-in-spa-mode) - [Minor Changes](#minor-changes-7) - - [Patch Changes](#patch-changes-19) + - [Patch Changes](#patch-changes-20) - [Unstable Changes](#unstable-changes-14) - [Split Route Modules (unstable)](#split-route-modules-unstable) - [Changes by Package](#changes-by-package-6) - [v7.1.5](#v715) - - [Patch Changes](#patch-changes-20) - - [v7.1.4](#v714) - [Patch Changes](#patch-changes-21) - - [v7.1.3](#v713) + - [v7.1.4](#v714) - [Patch Changes](#patch-changes-22) - - [v7.1.2](#v712) + - [v7.1.3](#v713) - [Patch Changes](#patch-changes-23) - - [v7.1.1](#v711) + - [v7.1.2](#v712) - [Patch Changes](#patch-changes-24) + - [v7.1.1](#v711) + - [Patch Changes](#patch-changes-25) - [v7.1.0](#v710) - [Minor Changes](#minor-changes-8) - - [Patch Changes](#patch-changes-25) + - [Patch Changes](#patch-changes-26) - [Changes by Package](#changes-by-package-7) - [v7.0.2](#v702) - - [Patch Changes](#patch-changes-26) - - [v7.0.1](#v701) - [Patch Changes](#patch-changes-27) + - [v7.0.1](#v701) + - [Patch Changes](#patch-changes-28) - [v7.0.0](#v700) - [Breaking Changes](#breaking-changes) - [Package Restructuring](#package-restructuring) @@ -143,201 +145,201 @@ We manage release notes in this file instead of the paginated Github Releases Pa - [Major Changes (`react-router`)](#major-changes-react-router) - [Major Changes (`@react-router/*`)](#major-changes-react-router-1) - [Minor Changes](#minor-changes-9) - - [Patch Changes](#patch-changes-28) + - [Patch Changes](#patch-changes-29) - [Changes by Package](#changes-by-package-8) - [React Router v6 Releases](#react-router-v6-releases) - [v6.30.1](#v6301) - - [Patch Changes](#patch-changes-29) + - [Patch Changes](#patch-changes-30) - [v6.30.0](#v6300) - [Minor Changes](#minor-changes-10) - - [Patch Changes](#patch-changes-30) + - [Patch Changes](#patch-changes-31) - [v6.29.0](#v6290) - [Minor Changes](#minor-changes-11) - - [Patch Changes](#patch-changes-31) - - [v6.28.2](#v6282) - [Patch Changes](#patch-changes-32) - - [v6.28.1](#v6281) + - [v6.28.2](#v6282) - [Patch Changes](#patch-changes-33) + - [v6.28.1](#v6281) + - [Patch Changes](#patch-changes-34) - [v6.28.0](#v6280) - [What's Changed](#whats-changed-7) - [Minor Changes](#minor-changes-12) - - [Patch Changes](#patch-changes-34) + - [Patch Changes](#patch-changes-35) - [v6.27.0](#v6270) - [What's Changed](#whats-changed-8) - [Stabilized APIs](#stabilized-apis) - [Minor Changes](#minor-changes-13) - - [Patch Changes](#patch-changes-35) - - [v6.26.2](#v6262) - [Patch Changes](#patch-changes-36) - - [v6.26.1](#v6261) + - [v6.26.2](#v6262) - [Patch Changes](#patch-changes-37) + - [v6.26.1](#v6261) + - [Patch Changes](#patch-changes-38) - [v6.26.0](#v6260) - [Minor Changes](#minor-changes-14) - - [Patch Changes](#patch-changes-38) - - [v6.25.1](#v6251) - [Patch Changes](#patch-changes-39) + - [v6.25.1](#v6251) + - [Patch Changes](#patch-changes-40) - [v6.25.0](#v6250) - [What's Changed](#whats-changed-9) - [Stabilized `v7_skipActionErrorRevalidation`](#stabilized-v7_skipactionerrorrevalidation) - [Minor Changes](#minor-changes-15) - - [Patch Changes](#patch-changes-40) - - [v6.24.1](#v6241) - [Patch Changes](#patch-changes-41) + - [v6.24.1](#v6241) + - [Patch Changes](#patch-changes-42) - [v6.24.0](#v6240) - [What's Changed](#whats-changed-10) - [Lazy Route Discovery (a.k.a. "Fog of War")](#lazy-route-discovery-aka-fog-of-war) - [Minor Changes](#minor-changes-16) - - [Patch Changes](#patch-changes-42) - - [v6.23.1](#v6231) - [Patch Changes](#patch-changes-43) + - [v6.23.1](#v6231) + - [Patch Changes](#patch-changes-44) - [v6.23.0](#v6230) - [What's Changed](#whats-changed-11) - [Data Strategy (unstable)](#data-strategy-unstable) - [Skip Action Error Revalidation (unstable)](#skip-action-error-revalidation-unstable) - [Minor Changes](#minor-changes-17) - [v6.22.3](#v6223) - - [Patch Changes](#patch-changes-44) - - [v6.22.2](#v6222) - [Patch Changes](#patch-changes-45) - - [v6.22.1](#v6221) + - [v6.22.2](#v6222) - [Patch Changes](#patch-changes-46) + - [v6.22.1](#v6221) + - [Patch Changes](#patch-changes-47) - [v6.22.0](#v6220) - [What's Changed](#whats-changed-12) - [Core Web Vitals Technology Report Flag](#core-web-vitals-technology-report-flag) - [Minor Changes](#minor-changes-18) - - [Patch Changes](#patch-changes-47) - - [v6.21.3](#v6213) - [Patch Changes](#patch-changes-48) - - [v6.21.2](#v6212) + - [v6.21.3](#v6213) - [Patch Changes](#patch-changes-49) - - [v6.21.1](#v6211) + - [v6.21.2](#v6212) - [Patch Changes](#patch-changes-50) + - [v6.21.1](#v6211) + - [Patch Changes](#patch-changes-51) - [v6.21.0](#v6210) - [What's Changed](#whats-changed-13) - [`future.v7_relativeSplatPath`](#futurev7_relativesplatpath) - [Partial Hydration](#partial-hydration) - [Minor Changes](#minor-changes-19) - - [Patch Changes](#patch-changes-51) - - [v6.20.1](#v6201) - [Patch Changes](#patch-changes-52) + - [v6.20.1](#v6201) + - [Patch Changes](#patch-changes-53) - [v6.20.0](#v6200) - [Minor Changes](#minor-changes-20) - - [Patch Changes](#patch-changes-53) + - [Patch Changes](#patch-changes-54) - [v6.19.0](#v6190) - [What's Changed](#whats-changed-14) - [`unstable_flushSync` API](#unstable_flushsync-api) - [Minor Changes](#minor-changes-21) - - [Patch Changes](#patch-changes-54) + - [Patch Changes](#patch-changes-55) - [v6.18.0](#v6180) - [What's Changed](#whats-changed-15) - [New Fetcher APIs](#new-fetcher-apis) - [Persistence Future Flag (`future.v7_fetcherPersist`)](#persistence-future-flag-futurev7_fetcherpersist) - [Minor Changes](#minor-changes-22) - - [Patch Changes](#patch-changes-55) + - [Patch Changes](#patch-changes-56) - [v6.17.0](#v6170) - [What's Changed](#whats-changed-16) - [View Transitions 🚀](#view-transitions-) - [Minor Changes](#minor-changes-23) - - [Patch Changes](#patch-changes-56) + - [Patch Changes](#patch-changes-57) - [v6.16.0](#v6160) - [Minor Changes](#minor-changes-24) - - [Patch Changes](#patch-changes-57) + - [Patch Changes](#patch-changes-58) - [v6.15.0](#v6150) - [Minor Changes](#minor-changes-25) - - [Patch Changes](#patch-changes-58) - - [v6.14.2](#v6142) - [Patch Changes](#patch-changes-59) - - [v6.14.1](#v6141) + - [v6.14.2](#v6142) - [Patch Changes](#patch-changes-60) + - [v6.14.1](#v6141) + - [Patch Changes](#patch-changes-61) - [v6.14.0](#v6140) - [What's Changed](#whats-changed-17) - [JSON/Text Submissions](#jsontext-submissions) - [Minor Changes](#minor-changes-26) - - [Patch Changes](#patch-changes-61) + - [Patch Changes](#patch-changes-62) - [v6.13.0](#v6130) - [What's Changed](#whats-changed-18) - [`future.v7_startTransition`](#futurev7_starttransition) - [Minor Changes](#minor-changes-27) - - [Patch Changes](#patch-changes-62) - - [v6.12.1](#v6121) - [Patch Changes](#patch-changes-63) + - [v6.12.1](#v6121) + - [Patch Changes](#patch-changes-64) - [v6.12.0](#v6120) - [What's Changed](#whats-changed-19) - [`React.startTransition` support](#reactstarttransition-support) - [Minor Changes](#minor-changes-28) - - [Patch Changes](#patch-changes-64) - - [v6.11.2](#v6112) - [Patch Changes](#patch-changes-65) - - [v6.11.1](#v6111) + - [v6.11.2](#v6112) - [Patch Changes](#patch-changes-66) + - [v6.11.1](#v6111) + - [Patch Changes](#patch-changes-67) - [v6.11.0](#v6110) - [Minor Changes](#minor-changes-29) - - [Patch Changes](#patch-changes-67) + - [Patch Changes](#patch-changes-68) - [v6.10.0](#v6100) - [What's Changed](#whats-changed-20) - [Minor Changes](#minor-changes-30) - [`future.v7_normalizeFormMethod`](#futurev7_normalizeformmethod) - - [Patch Changes](#patch-changes-68) + - [Patch Changes](#patch-changes-69) - [v6.9.0](#v690) - [What's Changed](#whats-changed-21) - [`Component`/`ErrorBoundary` route properties](#componenterrorboundary-route-properties) - [Introducing Lazy Route Modules](#introducing-lazy-route-modules) - [Minor Changes](#minor-changes-31) - - [Patch Changes](#patch-changes-69) - - [v6.8.2](#v682) - [Patch Changes](#patch-changes-70) - - [v6.8.1](#v681) + - [v6.8.2](#v682) - [Patch Changes](#patch-changes-71) + - [v6.8.1](#v681) + - [Patch Changes](#patch-changes-72) - [v6.8.0](#v680) - [Minor Changes](#minor-changes-32) - - [Patch Changes](#patch-changes-72) + - [Patch Changes](#patch-changes-73) - [v6.7.0](#v670) - [Minor Changes](#minor-changes-33) - - [Patch Changes](#patch-changes-73) - - [v6.6.2](#v662) - [Patch Changes](#patch-changes-74) - - [v6.6.1](#v661) + - [v6.6.2](#v662) - [Patch Changes](#patch-changes-75) + - [v6.6.1](#v661) + - [Patch Changes](#patch-changes-76) - [v6.6.0](#v660) - [What's Changed](#whats-changed-22) - [Minor Changes](#minor-changes-34) - - [Patch Changes](#patch-changes-76) + - [Patch Changes](#patch-changes-77) - [v6.5.0](#v650) - [What's Changed](#whats-changed-23) - [Minor Changes](#minor-changes-35) - - [Patch Changes](#patch-changes-77) - - [v6.4.5](#v645) - [Patch Changes](#patch-changes-78) - - [v6.4.4](#v644) + - [v6.4.5](#v645) - [Patch Changes](#patch-changes-79) - - [v6.4.3](#v643) + - [v6.4.4](#v644) - [Patch Changes](#patch-changes-80) - - [v6.4.2](#v642) + - [v6.4.3](#v643) - [Patch Changes](#patch-changes-81) - - [v6.4.1](#v641) + - [v6.4.2](#v642) - [Patch Changes](#patch-changes-82) + - [v6.4.1](#v641) + - [Patch Changes](#patch-changes-83) - [v6.4.0](#v640) - [What's Changed](#whats-changed-24) - [Remix Data APIs](#remix-data-apis) - - [Patch Changes](#patch-changes-83) + - [Patch Changes](#patch-changes-84) - [v6.3.0](#v630) - [Minor Changes](#minor-changes-36) - [v6.2.2](#v622) - - [Patch Changes](#patch-changes-84) - - [v6.2.1](#v621) - [Patch Changes](#patch-changes-85) + - [v6.2.1](#v621) + - [Patch Changes](#patch-changes-86) - [v6.2.0](#v620) - [Minor Changes](#minor-changes-37) - - [Patch Changes](#patch-changes-86) - - [v6.1.1](#v611) - [Patch Changes](#patch-changes-87) + - [v6.1.1](#v611) + - [Patch Changes](#patch-changes-88) - [v6.1.0](#v610) - [Minor Changes](#minor-changes-38) - - [Patch Changes](#patch-changes-88) - - [v6.0.2](#v602) - [Patch Changes](#patch-changes-89) - - [v6.0.1](#v601) + - [v6.0.2](#v602) - [Patch Changes](#patch-changes-90) + - [v6.0.1](#v601) + - [Patch Changes](#patch-changes-91) - [v6.0.0](#v600) @@ -365,6 +367,19 @@ Date: YYYY-MM-DD **Full Changelog**: [`v7.X.Y...v7.X.Y`](https://github.com/remix-run/react-router/compare/react-router@7.X.Y...react-router@7.X.Y) --> +## v7.9.3 + +Date: 2025-09-26 + +### Patch Changes + +- `react-router` - Fix Data Mode regression causing a 404 during initial load in when `middleware` exists without any `loader` functions ([#14393](https://github.com/remix-run/react-router/pull/14393)) +- `react-router` - Do not try to use `turbo-stream` to decode CDN errors that never reached the server ([#14385](https://github.com/remix-run/react-router/pull/14385)) + - This was logic we used to have in Remix v2 that got lost in the adoption of Single Fetch + - This permits the actual CDN error to bubble to the `ErrorBoundary` instead of a generic _"Unable to decode turbo-stream response"_ error + +**Full Changelog**: [`v7.9.2...v7.9.3`](https://github.com/remix-run/react-router/compare/react-router@7.9.2...react-router@7.9.3) + ## v7.9.2 Date: 2025-09-24 From 62aed9e44ce6097c9542d58ed21e7ad950d69c72 Mon Sep 17 00:00:00 2001 From: Matt Brophy Date: Fri, 26 Sep 2025 14:31:12 -0400 Subject: [PATCH 07/10] Exit prerelease mode --- .changeset/pre.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pre.json b/.changeset/pre.json index 09a02c7bce..9d8ca2b934 100644 --- a/.changeset/pre.json +++ b/.changeset/pre.json @@ -1,5 +1,5 @@ { - "mode": "pre", + "mode": "exit", "tag": "pre", "initialVersions": { "integration": "0.0.0", From 12a6719354315b0e6847475bd802098ccfe7d56a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Fri, 26 Sep 2025 15:42:01 -0400 Subject: [PATCH 08/10] chore: Update version for release (#14395) Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com> --- .changeset/happy-hornets-judge.md | 7 --- .changeset/pre.json | 43 ------------------- .changeset/twelve-dogs-pump.md | 5 --- integration/CHANGELOG.md | 1 + packages/create-react-router/CHANGELOG.md | 2 +- packages/create-react-router/package.json | 2 +- packages/react-router-architect/CHANGELOG.md | 9 ++-- packages/react-router-architect/package.json | 2 +- packages/react-router-cloudflare/CHANGELOG.md | 7 ++- packages/react-router-cloudflare/package.json | 2 +- packages/react-router-dev/CHANGELOG.md | 16 +++++-- packages/react-router-dev/package.json | 2 +- packages/react-router-dom/CHANGELOG.md | 4 +- packages/react-router-dom/package.json | 2 +- packages/react-router-express/CHANGELOG.md | 7 +-- packages/react-router-express/package.json | 2 +- packages/react-router-fs-routes/CHANGELOG.md | 4 +- packages/react-router-fs-routes/package.json | 2 +- packages/react-router-node/CHANGELOG.md | 9 +++- packages/react-router-node/package.json | 2 +- .../CHANGELOG.md | 4 +- .../package.json | 2 +- packages/react-router-serve/CHANGELOG.md | 10 +++-- packages/react-router-serve/package.json | 2 +- packages/react-router/CHANGELOG.md | 12 +++++- packages/react-router/package.json | 2 +- 26 files changed, 69 insertions(+), 93 deletions(-) delete mode 100644 .changeset/happy-hornets-judge.md delete mode 100644 .changeset/pre.json delete mode 100644 .changeset/twelve-dogs-pump.md diff --git a/.changeset/happy-hornets-judge.md b/.changeset/happy-hornets-judge.md deleted file mode 100644 index bb336a6b07..0000000000 --- a/.changeset/happy-hornets-judge.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"react-router": patch ---- - -Do not try to use `turbo-stream` to decode CDN errors that never reached the server - -- We used to do this but lost this check with the adoption of single fetch diff --git a/.changeset/pre.json b/.changeset/pre.json deleted file mode 100644 index 9d8ca2b934..0000000000 --- a/.changeset/pre.json +++ /dev/null @@ -1,43 +0,0 @@ -{ - "mode": "exit", - "tag": "pre", - "initialVersions": { - "integration": "0.0.0", - "integration-cloudflare-dev-proxy-template": "0.0.0", - "integration-rsc-parcel": "0.0.0", - "integration-rsc-vite": "0.0.0", - "integration-rsc-vite-framework": "0.0.0", - "integration-vite-5-template": "0.0.0", - "integration-vite-6-template": "0.0.0", - "integration-vite-7-beta-template": "0.0.0", - "integration-vite-plugin-cloudflare-template": "0.0.0", - "integration-vite-rolldown-template": "0.0.0", - "create-react-router": "7.9.2", - "react-router": "7.9.2", - "@react-router/architect": "7.9.2", - "@react-router/cloudflare": "7.9.2", - "@react-router/dev": "7.9.2", - "react-router-dom": "7.9.2", - "@react-router/express": "7.9.2", - "@react-router/fs-routes": "7.9.2", - "@react-router/node": "7.9.2", - "@react-router/remix-routes-option-adapter": "7.9.2", - "@react-router/serve": "7.9.2", - "@playground/framework": "0.0.0", - "@playground/framework-express": "0.0.0", - "@playground/framework-rolldown-vite": "0.0.0", - "@playground/framework-spa": "0.0.0", - "@playground/framework-vite-5": "0.0.0", - "@playground/framework-vite-7-beta": "0.0.0", - "@playground/rsc-parcel": "0.0.0", - "@playground/rsc-vite": "0.0.0", - "@playground/rsc-vite-framework": "0.0.0", - "@playground/split-route-modules": "0.0.0", - "@playground/split-route-modules-spa": "0.0.0", - "@playground/vite-plugin-cloudflare": "0.0.0" - }, - "changesets": [ - "happy-hornets-judge", - "twelve-dogs-pump" - ] -} diff --git a/.changeset/twelve-dogs-pump.md b/.changeset/twelve-dogs-pump.md deleted file mode 100644 index d61525d917..0000000000 --- a/.changeset/twelve-dogs-pump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": patch ---- - -Fix Data Mode regression causing a 404 during initial load in when `middleware` exists without any `loader` functions diff --git a/integration/CHANGELOG.md b/integration/CHANGELOG.md index 2cf67d87b7..6fccf850d7 100644 --- a/integration/CHANGELOG.md +++ b/integration/CHANGELOG.md @@ -5,6 +5,7 @@ ### Minor Changes - Unstable Vite support for Node-based Remix apps ([#7590](https://github.com/remix-run/remix/pull/7590)) + - `remix build` 👉 `vite build && vite build --ssr` - `remix dev` 👉 `vite dev` diff --git a/packages/create-react-router/CHANGELOG.md b/packages/create-react-router/CHANGELOG.md index 16eaa1cf95..da45cd74b2 100644 --- a/packages/create-react-router/CHANGELOG.md +++ b/packages/create-react-router/CHANGELOG.md @@ -1,6 +1,6 @@ # `create-react-router` -## 7.9.3-pre.0 +## 7.9.3 ## 7.9.2 diff --git a/packages/create-react-router/package.json b/packages/create-react-router/package.json index f398e07216..f0eab96b1a 100644 --- a/packages/create-react-router/package.json +++ b/packages/create-react-router/package.json @@ -1,6 +1,6 @@ { "name": "create-react-router", - "version": "7.9.3-pre.0", + "version": "7.9.3", "description": "Create a new React Router app", "homepage": "https://reactrouter.com", "bugs": { diff --git a/packages/react-router-architect/CHANGELOG.md b/packages/react-router-architect/CHANGELOG.md index 215666cfd3..4f04a6878b 100644 --- a/packages/react-router-architect/CHANGELOG.md +++ b/packages/react-router-architect/CHANGELOG.md @@ -1,12 +1,12 @@ # `@react-router/architect` -## 7.9.3-pre.0 +## 7.9.3 ### Patch Changes - Updated dependencies: - - `react-router@7.9.3-pre.0` - - `@react-router/node@7.9.3-pre.0` + - `react-router@7.9.3` + - `@react-router/node@7.9.3` ## 7.9.2 @@ -31,6 +31,7 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: + - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -254,6 +255,7 @@ ### Major Changes - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) + - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -262,6 +264,7 @@ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: + - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` diff --git a/packages/react-router-architect/package.json b/packages/react-router-architect/package.json index ad5b9504dd..9b63583c6f 100644 --- a/packages/react-router-architect/package.json +++ b/packages/react-router-architect/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/architect", - "version": "7.9.3-pre.0", + "version": "7.9.3", "description": "Architect server request handler for React Router", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-cloudflare/CHANGELOG.md b/packages/react-router-cloudflare/CHANGELOG.md index 5a2bb296b1..f2dac5adcc 100644 --- a/packages/react-router-cloudflare/CHANGELOG.md +++ b/packages/react-router-cloudflare/CHANGELOG.md @@ -1,11 +1,11 @@ # `@react-router/cloudflare` -## 7.9.3-pre.0 +## 7.9.3 ### Patch Changes - Updated dependencies: - - `react-router@7.9.3-pre.0` + - `react-router@7.9.3` ## 7.9.2 @@ -28,6 +28,7 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: + - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -226,6 +227,7 @@ - For Remix consumers migrating to React Router, all exports from `@remix-run/cloudflare-pages` are now provided for React Router consumers in the `@react-router/cloudflare` package. There is no longer a separate package for Cloudflare Pages. ([#11801](https://github.com/remix-run/react-router/pull/11801)) - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) + - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -234,6 +236,7 @@ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: + - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` diff --git a/packages/react-router-cloudflare/package.json b/packages/react-router-cloudflare/package.json index 44626ea7b6..249f43f0f8 100644 --- a/packages/react-router-cloudflare/package.json +++ b/packages/react-router-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/cloudflare", - "version": "7.9.3-pre.0", + "version": "7.9.3", "description": "Cloudflare platform abstractions for React Router", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-dev/CHANGELOG.md b/packages/react-router-dev/CHANGELOG.md index 200adcdab4..a3adc9c1b5 100644 --- a/packages/react-router-dev/CHANGELOG.md +++ b/packages/react-router-dev/CHANGELOG.md @@ -1,13 +1,13 @@ # `@react-router/dev` -## 7.9.3-pre.0 +## 7.9.3 ### Patch Changes - Updated dependencies: - - `react-router@7.9.3-pre.0` - - `@react-router/node@7.9.3-pre.0` - - `@react-router/serve@7.9.3-pre.0` + - `react-router@7.9.3` + - `@react-router/node@7.9.3` + - `@react-router/serve@7.9.3` ## 7.9.2 @@ -45,6 +45,7 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: + - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -787,6 +788,7 @@ ``` This initial implementation targets type inference for: + - `Params` : Path parameters from your routing config in `routes.ts` including file-based routing - `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module - `ActionData` : Action data from `action` and/or `clientAction` within your route module @@ -801,6 +803,7 @@ ``` Check out our docs for more: + - [_Explanations > Type Safety_](https://reactrouter.com/dev/guides/explanation/type-safety) - [_How-To > Setting up type safety_](https://reactrouter.com/dev/guides/how-to/setting-up-type-safety) @@ -1000,6 +1003,7 @@ - Vite: Provide `Unstable_ServerBundlesFunction` and `Unstable_VitePluginConfig` types ([#8654](https://github.com/remix-run/remix/pull/8654)) - Vite: add `--sourcemapClient` and `--sourcemapServer` flags to `remix vite:build` ([#8613](https://github.com/remix-run/remix/pull/8613)) + - `--sourcemapClient` - `--sourcemapClient=inline` @@ -1336,6 +1340,7 @@ - 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)) 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: + - Leveraging a data source local to the browser (i.e., `localStorage`) - Managing a client-side cache of server data (like `IndexedDB`) - Bypassing the Remix server in a BFF setup and hitting your API directly from the browser @@ -1739,6 +1744,7 @@ - Output esbuild metafiles for bundle analysis ([#6772](https://github.com/remix-run/remix/pull/6772)) Written to server build directory (`build/` by default): + - `metafile.css.json` - `metafile.js.json` (browser JS) - `metafile.server.json` (server JS) @@ -1836,6 +1842,7 @@ - built-in tls support ([#6483](https://github.com/remix-run/remix/pull/6483)) New options: + - `--tls-key` / `tlsKey`: TLS key - `--tls-cert` / `tlsCert`: TLS Certificate @@ -2106,6 +2113,7 @@ ``` The dev server will: + - force `NODE_ENV=development` and warn you if it was previously set to something else - rebuild your app whenever your Remix app code changes - restart your app server whenever rebuilds succeed diff --git a/packages/react-router-dev/package.json b/packages/react-router-dev/package.json index 8284f7f433..5d8c1a0e17 100644 --- a/packages/react-router-dev/package.json +++ b/packages/react-router-dev/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/dev", - "version": "7.9.3-pre.0", + "version": "7.9.3", "description": "Dev tools and CLI for React Router", "homepage": "https://reactrouter.com", "bugs": { diff --git a/packages/react-router-dom/CHANGELOG.md b/packages/react-router-dom/CHANGELOG.md index d5b0728090..75c2ecb0ef 100644 --- a/packages/react-router-dom/CHANGELOG.md +++ b/packages/react-router-dom/CHANGELOG.md @@ -1,11 +1,11 @@ # react-router-dom -## 7.9.3-pre.0 +## 7.9.3 ### Patch Changes - Updated dependencies: - - `react-router@7.9.3-pre.0` + - `react-router@7.9.3` ## 7.9.2 diff --git a/packages/react-router-dom/package.json b/packages/react-router-dom/package.json index 0a7f320ded..715770624e 100644 --- a/packages/react-router-dom/package.json +++ b/packages/react-router-dom/package.json @@ -1,6 +1,6 @@ { "name": "react-router-dom", - "version": "7.9.3-pre.0", + "version": "7.9.3", "description": "Declarative routing for React web applications", "keywords": [ "react", diff --git a/packages/react-router-express/CHANGELOG.md b/packages/react-router-express/CHANGELOG.md index dc425040d2..7504642bc9 100644 --- a/packages/react-router-express/CHANGELOG.md +++ b/packages/react-router-express/CHANGELOG.md @@ -1,12 +1,12 @@ # `@react-router/express` -## 7.9.3-pre.0 +## 7.9.3 ### Patch Changes - Updated dependencies: - - `react-router@7.9.3-pre.0` - - `@react-router/node@7.9.3-pre.0` + - `react-router@7.9.3` + - `@react-router/node@7.9.3` ## 7.9.2 @@ -31,6 +31,7 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: + - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option diff --git a/packages/react-router-express/package.json b/packages/react-router-express/package.json index b8f3bff83a..18f5bf6a13 100644 --- a/packages/react-router-express/package.json +++ b/packages/react-router-express/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/express", - "version": "7.9.3-pre.0", + "version": "7.9.3", "description": "Express server request handler for React Router", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-fs-routes/CHANGELOG.md b/packages/react-router-fs-routes/CHANGELOG.md index ba2642580e..0153883a9c 100644 --- a/packages/react-router-fs-routes/CHANGELOG.md +++ b/packages/react-router-fs-routes/CHANGELOG.md @@ -1,11 +1,11 @@ # `@react-router/fs-routes` -## 7.9.3-pre.0 +## 7.9.3 ### Patch Changes - Updated dependencies: - - `@react-router/dev@7.9.3-pre.0` + - `@react-router/dev@7.9.3` ## 7.9.2 diff --git a/packages/react-router-fs-routes/package.json b/packages/react-router-fs-routes/package.json index b75ff9cb13..d7728fd930 100644 --- a/packages/react-router-fs-routes/package.json +++ b/packages/react-router-fs-routes/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/fs-routes", - "version": "7.9.3-pre.0", + "version": "7.9.3", "description": "File system routing conventions for React Router, for use within routes.ts", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-node/CHANGELOG.md b/packages/react-router-node/CHANGELOG.md index 1537ba9c60..226fdbe953 100644 --- a/packages/react-router-node/CHANGELOG.md +++ b/packages/react-router-node/CHANGELOG.md @@ -1,11 +1,11 @@ # `@react-router/node` -## 7.9.3-pre.0 +## 7.9.3 ### Patch Changes - Updated dependencies: - - `react-router@7.9.3-pre.0` + - `react-router@7.9.3` ## 7.9.2 @@ -28,6 +28,7 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: + - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -227,6 +228,7 @@ - Remove single fetch future flag. ([#11522](https://github.com/remix-run/react-router/pull/11522)) - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) + - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -235,6 +237,7 @@ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: + - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` @@ -642,10 +645,12 @@ - Introduces the `defer()` API from `@remix-run/router` with support for server-rendering and HTTP streaming. This utility allows you to defer values returned from `loader` functions by returning promises instead of resolved values. This has been refered to as _"sending a promise over the wire"_. ([#4920](https://github.com/remix-run/remix/pull/4920)) Informational Resources: + - - Documentation Resources (better docs specific to Remix are in the works): + - - - diff --git a/packages/react-router-node/package.json b/packages/react-router-node/package.json index d7019d9e2d..be542771c3 100644 --- a/packages/react-router-node/package.json +++ b/packages/react-router-node/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/node", - "version": "7.9.3-pre.0", + "version": "7.9.3", "description": "Node.js platform abstractions for React Router", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-remix-routes-option-adapter/CHANGELOG.md b/packages/react-router-remix-routes-option-adapter/CHANGELOG.md index 54e96e0020..7d95d12953 100644 --- a/packages/react-router-remix-routes-option-adapter/CHANGELOG.md +++ b/packages/react-router-remix-routes-option-adapter/CHANGELOG.md @@ -1,11 +1,11 @@ # `@react-router/remix-config-routes-adapter` -## 7.9.3-pre.0 +## 7.9.3 ### Patch Changes - Updated dependencies: - - `@react-router/dev@7.9.3-pre.0` + - `@react-router/dev@7.9.3` ## 7.9.2 diff --git a/packages/react-router-remix-routes-option-adapter/package.json b/packages/react-router-remix-routes-option-adapter/package.json index f2cc6e4094..691b5353ab 100644 --- a/packages/react-router-remix-routes-option-adapter/package.json +++ b/packages/react-router-remix-routes-option-adapter/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/remix-routes-option-adapter", - "version": "7.9.3-pre.0", + "version": "7.9.3", "description": "Adapter for Remix's \"routes\" config option, for use within routes.ts", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router-serve/CHANGELOG.md b/packages/react-router-serve/CHANGELOG.md index 6a1e5aea06..ad9e156f40 100644 --- a/packages/react-router-serve/CHANGELOG.md +++ b/packages/react-router-serve/CHANGELOG.md @@ -1,13 +1,13 @@ # `@react-router/serve` -## 7.9.3-pre.0 +## 7.9.3 ### Patch Changes - Updated dependencies: - - `react-router@7.9.3-pre.0` - - `@react-router/node@7.9.3-pre.0` - - `@react-router/express@7.9.3-pre.0` + - `react-router@7.9.3` + - `@react-router/node@7.9.3` + - `@react-router/express@7.9.3` ## 7.9.2 @@ -645,10 +645,12 @@ - Introduces the `defer()` API from `@remix-run/router` with support for server-rendering and HTTP streaming. This utility allows you to defer values returned from `loader` functions by returning promises instead of resolved values. This has been refered to as _"sending a promise over the wire"_. ([#4920](https://github.com/remix-run/remix/pull/4920)) Informational Resources: + - - Documentation Resources (better docs specific to Remix are in the works): + - - - diff --git a/packages/react-router-serve/package.json b/packages/react-router-serve/package.json index e3776299ae..4d42b286a5 100644 --- a/packages/react-router-serve/package.json +++ b/packages/react-router-serve/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/serve", - "version": "7.9.3-pre.0", + "version": "7.9.3", "description": "Production application server for React Router", "bugs": { "url": "https://github.com/remix-run/react-router/issues" diff --git a/packages/react-router/CHANGELOG.md b/packages/react-router/CHANGELOG.md index 7fbd81f324..f7d25f8b71 100644 --- a/packages/react-router/CHANGELOG.md +++ b/packages/react-router/CHANGELOG.md @@ -1,6 +1,6 @@ # `react-router` -## 7.9.3-pre.0 +## 7.9.3 ### Patch Changes @@ -48,6 +48,7 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: + - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -74,7 +75,7 @@ - \[UNSTABLE] Add ``/`` prop for client side error reporting ([#14162](https://github.com/remix-run/react-router/pull/14162)) -- server action revalidation opt out via $SKIP_REVALIDATION field ([#14154](https://github.com/remix-run/react-router/pull/14154)) +- server action revalidation opt out via $SKIP\_REVALIDATION field ([#14154](https://github.com/remix-run/react-router/pull/14154)) - Properly escape interpolated param values in `generatePath()` ([#13530](https://github.com/remix-run/react-router/pull/13530)) @@ -123,6 +124,7 @@ - Remove dependency on `@types/node` in TypeScript declaration files ([#14059](https://github.com/remix-run/react-router/pull/14059)) - Fix types for `UIMatch` to reflect that the `loaderData`/`data` properties may be `undefined` ([#12206](https://github.com/remix-run/react-router/pull/12206)) + - When an `ErrorBoundary` is being rendered, not all active matches will have loader data available, since it may have been their `loader` that threw to trigger the boundary - The `UIMatch.data` type was not correctly handing this and would always reflect the presence of data, leading to the unexpected runtime errors when an `ErrorBoundary` was rendered - ⚠️ This may cause some type errors to show up in your code for unguarded `match.data` accesses - you should properly guard for `undefined` values in those scenarios. @@ -156,6 +158,7 @@ - \[UNSTABLE] When middleware is enabled, make the `context` parameter read-only (via `Readonly`) so that TypeScript will not allow you to write arbitrary fields to it in loaders, actions, or middleware. ([#14097](https://github.com/remix-run/react-router/pull/14097)) - \[UNSTABLE] Rename and alter the signature/functionality of the `unstable_respond` API in `staticHandler.query`/`staticHandler.queryRoute` ([#14103](https://github.com/remix-run/react-router/pull/14103)) + - The API has been renamed to `unstable_generateMiddlewareResponse` for clarity - The main functional change is that instead of running the loaders/actions before calling `unstable_respond` and handing you the result, we now pass a `query`/`queryRoute` function as a parameter and you execute the loaders/actions inside your callback, giving you full access to pre-processing and error handling - The `query` version of the API now has a signature of `(query: (r: Request) => Promise) => Promise` @@ -801,6 +804,7 @@ ``` Similar to server-side requests, a fresh `context` will be created per navigation (or `fetcher` call). If you have initial data you'd like to populate in the context for every request, you can provide an `unstable_getContext` function at the root of your app: + - Library mode - `createBrowserRouter(routes, { unstable_getContext })` - Framework mode - `` @@ -988,6 +992,7 @@ _No changes_ - Remove `future.v7_normalizeFormMethod` future flag ([#11697](https://github.com/remix-run/react-router/pull/11697)) - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) + - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -996,6 +1001,7 @@ _No changes_ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: + - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` @@ -1151,6 +1157,7 @@ _No changes_ ``` This initial implementation targets type inference for: + - `Params` : Path parameters from your routing config in `routes.ts` including file-based routing - `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module - `ActionData` : Action data from `action` and/or `clientAction` within your route module @@ -1165,6 +1172,7 @@ _No changes_ ``` Check out our docs for more: + - [_Explanations > Type Safety_](https://reactrouter.com/dev/guides/explanation/type-safety) - [_How-To > Setting up type safety_](https://reactrouter.com/dev/guides/how-to/setting-up-type-safety) diff --git a/packages/react-router/package.json b/packages/react-router/package.json index 471596b12b..563bcad27c 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -1,6 +1,6 @@ { "name": "react-router", - "version": "7.9.3-pre.0", + "version": "7.9.3", "description": "Declarative routing for React", "keywords": [ "react", From 2b592a39ff958ba3943eff080427b08500ae60ab Mon Sep 17 00:00:00 2001 From: Remix Run Bot Date: Fri, 26 Sep 2025 19:43:16 +0000 Subject: [PATCH 09/10] chore: format --- integration/CHANGELOG.md | 1 - packages/react-router-architect/CHANGELOG.md | 3 --- packages/react-router-cloudflare/CHANGELOG.md | 3 --- packages/react-router-dev/CHANGELOG.md | 8 -------- packages/react-router-express/CHANGELOG.md | 1 - packages/react-router-node/CHANGELOG.md | 5 ----- packages/react-router-serve/CHANGELOG.md | 2 -- packages/react-router/CHANGELOG.md | 10 +--------- 8 files changed, 1 insertion(+), 32 deletions(-) diff --git a/integration/CHANGELOG.md b/integration/CHANGELOG.md index 6fccf850d7..2cf67d87b7 100644 --- a/integration/CHANGELOG.md +++ b/integration/CHANGELOG.md @@ -5,7 +5,6 @@ ### Minor Changes - Unstable Vite support for Node-based Remix apps ([#7590](https://github.com/remix-run/remix/pull/7590)) - - `remix build` 👉 `vite build && vite build --ssr` - `remix dev` 👉 `vite dev` diff --git a/packages/react-router-architect/CHANGELOG.md b/packages/react-router-architect/CHANGELOG.md index 4f04a6878b..5ec74a1162 100644 --- a/packages/react-router-architect/CHANGELOG.md +++ b/packages/react-router-architect/CHANGELOG.md @@ -31,7 +31,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -255,7 +254,6 @@ ### Major Changes - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) - - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -264,7 +262,6 @@ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: - - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` diff --git a/packages/react-router-cloudflare/CHANGELOG.md b/packages/react-router-cloudflare/CHANGELOG.md index f2dac5adcc..d74b9aa8d9 100644 --- a/packages/react-router-cloudflare/CHANGELOG.md +++ b/packages/react-router-cloudflare/CHANGELOG.md @@ -28,7 +28,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -227,7 +226,6 @@ - For Remix consumers migrating to React Router, all exports from `@remix-run/cloudflare-pages` are now provided for React Router consumers in the `@react-router/cloudflare` package. There is no longer a separate package for Cloudflare Pages. ([#11801](https://github.com/remix-run/react-router/pull/11801)) - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) - - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -236,7 +234,6 @@ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: - - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` diff --git a/packages/react-router-dev/CHANGELOG.md b/packages/react-router-dev/CHANGELOG.md index a3adc9c1b5..2d0aa8e6df 100644 --- a/packages/react-router-dev/CHANGELOG.md +++ b/packages/react-router-dev/CHANGELOG.md @@ -45,7 +45,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -788,7 +787,6 @@ ``` This initial implementation targets type inference for: - - `Params` : Path parameters from your routing config in `routes.ts` including file-based routing - `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module - `ActionData` : Action data from `action` and/or `clientAction` within your route module @@ -803,7 +801,6 @@ ``` Check out our docs for more: - - [_Explanations > Type Safety_](https://reactrouter.com/dev/guides/explanation/type-safety) - [_How-To > Setting up type safety_](https://reactrouter.com/dev/guides/how-to/setting-up-type-safety) @@ -1003,7 +1000,6 @@ - Vite: Provide `Unstable_ServerBundlesFunction` and `Unstable_VitePluginConfig` types ([#8654](https://github.com/remix-run/remix/pull/8654)) - Vite: add `--sourcemapClient` and `--sourcemapServer` flags to `remix vite:build` ([#8613](https://github.com/remix-run/remix/pull/8613)) - - `--sourcemapClient` - `--sourcemapClient=inline` @@ -1340,7 +1336,6 @@ - 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)) 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: - - Leveraging a data source local to the browser (i.e., `localStorage`) - Managing a client-side cache of server data (like `IndexedDB`) - Bypassing the Remix server in a BFF setup and hitting your API directly from the browser @@ -1744,7 +1739,6 @@ - Output esbuild metafiles for bundle analysis ([#6772](https://github.com/remix-run/remix/pull/6772)) Written to server build directory (`build/` by default): - - `metafile.css.json` - `metafile.js.json` (browser JS) - `metafile.server.json` (server JS) @@ -1842,7 +1836,6 @@ - built-in tls support ([#6483](https://github.com/remix-run/remix/pull/6483)) New options: - - `--tls-key` / `tlsKey`: TLS key - `--tls-cert` / `tlsCert`: TLS Certificate @@ -2113,7 +2106,6 @@ ``` The dev server will: - - force `NODE_ENV=development` and warn you if it was previously set to something else - rebuild your app whenever your Remix app code changes - restart your app server whenever rebuilds succeed diff --git a/packages/react-router-express/CHANGELOG.md b/packages/react-router-express/CHANGELOG.md index 7504642bc9..d3e49f9170 100644 --- a/packages/react-router-express/CHANGELOG.md +++ b/packages/react-router-express/CHANGELOG.md @@ -31,7 +31,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option diff --git a/packages/react-router-node/CHANGELOG.md b/packages/react-router-node/CHANGELOG.md index 226fdbe953..8955ab93d2 100644 --- a/packages/react-router-node/CHANGELOG.md +++ b/packages/react-router-node/CHANGELOG.md @@ -28,7 +28,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -228,7 +227,6 @@ - Remove single fetch future flag. ([#11522](https://github.com/remix-run/react-router/pull/11522)) - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) - - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -237,7 +235,6 @@ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: - - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` @@ -645,12 +642,10 @@ - Introduces the `defer()` API from `@remix-run/router` with support for server-rendering and HTTP streaming. This utility allows you to defer values returned from `loader` functions by returning promises instead of resolved values. This has been refered to as _"sending a promise over the wire"_. ([#4920](https://github.com/remix-run/remix/pull/4920)) Informational Resources: - - - Documentation Resources (better docs specific to Remix are in the works): - - - - diff --git a/packages/react-router-serve/CHANGELOG.md b/packages/react-router-serve/CHANGELOG.md index ad9e156f40..cb2c8edc65 100644 --- a/packages/react-router-serve/CHANGELOG.md +++ b/packages/react-router-serve/CHANGELOG.md @@ -645,12 +645,10 @@ - Introduces the `defer()` API from `@remix-run/router` with support for server-rendering and HTTP streaming. This utility allows you to defer values returned from `loader` functions by returning promises instead of resolved values. This has been refered to as _"sending a promise over the wire"_. ([#4920](https://github.com/remix-run/remix/pull/4920)) Informational Resources: - - - Documentation Resources (better docs specific to Remix are in the works): - - - - diff --git a/packages/react-router/CHANGELOG.md b/packages/react-router/CHANGELOG.md index f7d25f8b71..2f0d19ed90 100644 --- a/packages/react-router/CHANGELOG.md +++ b/packages/react-router/CHANGELOG.md @@ -48,7 +48,6 @@ - Stabilize middleware and context APIs. ([#14215](https://github.com/remix-run/react-router/pull/14215)) We have removed the `unstable_` prefix from the following APIs and they are now considered stable and ready for production use: - - [`RouterContextProvider`](https://reactrouter.com/api/utils/RouterContextProvider) - [`createContext`](https://reactrouter.com/api/utils/createContext) - `createBrowserRouter` [`getContext`](https://reactrouter.com/api/data-routers/createBrowserRouter#optsgetcontext) option @@ -75,7 +74,7 @@ - \[UNSTABLE] Add ``/`` prop for client side error reporting ([#14162](https://github.com/remix-run/react-router/pull/14162)) -- server action revalidation opt out via $SKIP\_REVALIDATION field ([#14154](https://github.com/remix-run/react-router/pull/14154)) +- server action revalidation opt out via $SKIP_REVALIDATION field ([#14154](https://github.com/remix-run/react-router/pull/14154)) - Properly escape interpolated param values in `generatePath()` ([#13530](https://github.com/remix-run/react-router/pull/13530)) @@ -124,7 +123,6 @@ - Remove dependency on `@types/node` in TypeScript declaration files ([#14059](https://github.com/remix-run/react-router/pull/14059)) - Fix types for `UIMatch` to reflect that the `loaderData`/`data` properties may be `undefined` ([#12206](https://github.com/remix-run/react-router/pull/12206)) - - When an `ErrorBoundary` is being rendered, not all active matches will have loader data available, since it may have been their `loader` that threw to trigger the boundary - The `UIMatch.data` type was not correctly handing this and would always reflect the presence of data, leading to the unexpected runtime errors when an `ErrorBoundary` was rendered - ⚠️ This may cause some type errors to show up in your code for unguarded `match.data` accesses - you should properly guard for `undefined` values in those scenarios. @@ -158,7 +156,6 @@ - \[UNSTABLE] When middleware is enabled, make the `context` parameter read-only (via `Readonly`) so that TypeScript will not allow you to write arbitrary fields to it in loaders, actions, or middleware. ([#14097](https://github.com/remix-run/react-router/pull/14097)) - \[UNSTABLE] Rename and alter the signature/functionality of the `unstable_respond` API in `staticHandler.query`/`staticHandler.queryRoute` ([#14103](https://github.com/remix-run/react-router/pull/14103)) - - The API has been renamed to `unstable_generateMiddlewareResponse` for clarity - The main functional change is that instead of running the loaders/actions before calling `unstable_respond` and handing you the result, we now pass a `query`/`queryRoute` function as a parameter and you execute the loaders/actions inside your callback, giving you full access to pre-processing and error handling - The `query` version of the API now has a signature of `(query: (r: Request) => Promise) => Promise` @@ -804,7 +801,6 @@ ``` Similar to server-side requests, a fresh `context` will be created per navigation (or `fetcher` call). If you have initial data you'd like to populate in the context for every request, you can provide an `unstable_getContext` function at the root of your app: - - Library mode - `createBrowserRouter(routes, { unstable_getContext })` - Framework mode - `` @@ -992,7 +988,6 @@ _No changes_ - Remove `future.v7_normalizeFormMethod` future flag ([#11697](https://github.com/remix-run/react-router/pull/11697)) - For Remix consumers migrating to React Router, the `crypto` global from the [Web Crypto API](https://developer.mozilla.org/en-US/docs/Web/API/Web_Crypto_API) is now required when using cookie and session APIs. This means that the following APIs are provided from `react-router` rather than platform-specific packages: ([#11837](https://github.com/remix-run/react-router/pull/11837)) - - `createCookie` - `createCookieSessionStorage` - `createMemorySessionStorage` @@ -1001,7 +996,6 @@ _No changes_ For consumers running older versions of Node, the `installGlobals` function from `@remix-run/node` has been updated to define `globalThis.crypto`, using [Node's `require('node:crypto').webcrypto` implementation.](https://nodejs.org/api/webcrypto.html) Since platform-specific packages no longer need to implement this API, the following low-level APIs have been removed: - - `createCookieFactory` - `createSessionStorageFactory` - `createCookieSessionStorageFactory` @@ -1157,7 +1151,6 @@ _No changes_ ``` This initial implementation targets type inference for: - - `Params` : Path parameters from your routing config in `routes.ts` including file-based routing - `LoaderData` : Loader data from `loader` and/or `clientLoader` within your route module - `ActionData` : Action data from `action` and/or `clientAction` within your route module @@ -1172,7 +1165,6 @@ _No changes_ ``` Check out our docs for more: - - [_Explanations > Type Safety_](https://reactrouter.com/dev/guides/explanation/type-safety) - [_How-To > Setting up type safety_](https://reactrouter.com/dev/guides/how-to/setting-up-type-safety) From 7fc52951e5a8d567f32536476a061a859f7af3cf Mon Sep 17 00:00:00 2001 From: Brooks Lybrand Date: Fri, 26 Sep 2025 14:58:37 -0500 Subject: [PATCH 10/10] docs: update deployment guides for Vercel, Cloudflare, and Netlify with links to official templates (#14397) --- docs/start/framework/deploying.md | 31 +++---------------------------- 1 file changed, 3 insertions(+), 28 deletions(-) diff --git a/docs/start/framework/deploying.md b/docs/start/framework/deploying.md index 1ed1dee57f..74e3165166 100644 --- a/docs/start/framework/deploying.md +++ b/docs/start/framework/deploying.md @@ -81,37 +81,12 @@ The containerized application can be deployed to any platform that supports Dock ### Vercel -``` -npx create-react-router@latest --template remix-run/react-router-templates/vercel -``` - -- Server Rendering -- Tailwind CSS - -### Cloudflare Workers w/ D1 - -``` -npx create-react-router@latest --template remix-run/react-router-templates/cloudflare-d1 -``` - -- Server Rendering -- D1 Database with Drizzle ORM -- Tailwind CSS +Vercel maintains their own template for React Router. Checkout the [Vercel Guide](https://vercel.com/templates/react-router/react-router-boilerplate) for more information. ### Cloudflare Workers -``` -npx create-react-router@latest --template remix-run/react-router-templates/cloudflare -``` - -- Server Rendering -- Tailwind CSS +Cloudflare maintains their own template for React Router. Checkout the [Cloudflare Guide](https://developers.cloudflare.com/workers/framework-guides/web-apps/react-router/) for more information. ### Netlify -``` -npx create-react-router@latest --template remix-run/react-router-templates/netlify -``` - -- Server Rendering -- Tailwind CSS +Netlify maintains their own template for React Router. Checkout the [Netlify Guide](https://docs.netlify.com/build/frameworks/framework-setup-guides/react-router/) for more information.