diff --git a/.changeset/angry-papayas-flow.md b/.changeset/angry-papayas-flow.md deleted file mode 100644 index d7b586ecd9..0000000000 --- a/.changeset/angry-papayas-flow.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"@react-router/dev": major ---- - -For Remix consumers migrating to React Router, the `vitePlugin` and `cloudflareDevProxyVitePlugin` exports have been renamed and moved. - -```diff --import { -- vitePlugin as remix, -- cloudflareDevProxyVitePlugin, --} from "@remix/dev"; - -+import { reactRouter } from "@react-router/dev/vite"; -+import { cloudflareDevProxy } from "@react-router/dev/vite/cloudflare"; -``` diff --git a/.changeset/calm-frogs-tie.md b/.changeset/calm-frogs-tie.md deleted file mode 100644 index f7f7b34b94..0000000000 --- a/.changeset/calm-frogs-tie.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-router/cloudflare": major ---- - -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. diff --git a/.changeset/calm-wombats-design.md b/.changeset/calm-wombats-design.md deleted file mode 100644 index 5b74838f7a..0000000000 --- a/.changeset/calm-wombats-design.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"react-router-dom": patch -"react-router": patch -"@remix-run/router": patch ---- - -- Fix bug when submitting to the current contextual route (parent route with an index child) when an `?index` param already exists from a prior submission -- Fix `useFormAction` bug - when removing `?index` param it would not keep other non-Remix `index` params diff --git a/.changeset/chatty-impalas-pump.md b/.changeset/chatty-impalas-pump.md deleted file mode 100644 index d630262cf8..0000000000 --- a/.changeset/chatty-impalas-pump.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@remix-run/router": patch ---- - -Fix bug with fetchers not persisting `preventScrollReset` through redirects during concurrent fetches diff --git a/.changeset/chilled-masks-search.md b/.changeset/chilled-masks-search.md deleted file mode 100644 index 2dfd04cf76..0000000000 --- a/.changeset/chilled-masks-search.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"react-router-dom": major -"react-router": major ---- - -Remove the original `defer` implementation in favor of using raw promises via single fetch and `turbo-stream`. This removes these exports from React Router: - -- `defer` -- `AbortedDeferredError` -- `type TypedDeferredData` -- `UNSAFE_DeferredData` -- `UNSAFE_DEFERRED_SYMBOL`, diff --git a/.changeset/collapse-packages.md b/.changeset/collapse-packages.md deleted file mode 100644 index 0903b92255..0000000000 --- a/.changeset/collapse-packages.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"react-router": major ---- - -- Collapse `@remix-run/router` into `react-router` -- Collapse `react-router-dom` into `react-router` -- Collapse `@remix-run/server-runtime` into `react-router` -- Collapse `@remix-run/testing` into `react-router` diff --git a/.changeset/config.json b/.changeset/config.json index 94aedefff9..19a0281431 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -7,13 +7,16 @@ "commit": false, "fixed": [ [ + "create-react-router", "react-router", "react-router-dom", "@react-router/architect", "@react-router/cloudflare", "@react-router/dev", + "@react-router/fs-routes", "@react-router/express", "@react-router/node", + "@react-router/remix-routes-option-adapter", "@react-router/serve" ] ], diff --git a/.changeset/create-remix-router.md b/.changeset/create-remix-router.md deleted file mode 100644 index 8c13e9371f..0000000000 --- a/.changeset/create-remix-router.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router-dom": major ---- - -Use `createRemixRouter`/`RouterProvider` in `entry.client` instead of `RemixBrowser` diff --git a/.changeset/curvy-teachers-explain.md b/.changeset/curvy-teachers-explain.md deleted file mode 100644 index d039d91976..0000000000 --- a/.changeset/curvy-teachers-explain.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"react-router-dom": major -"@react-router/express": major -"react-router": major -"@react-router/serve": major -"@react-router/node": major -"@react-router/dev": major ---- - -Remove single_fetch future flag. diff --git a/.changeset/drop-node-16.md b/.changeset/drop-node-16.md deleted file mode 100644 index be3759da73..0000000000 --- a/.changeset/drop-node-16.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": major ---- - -Drop support for Node 16, React Router SSR now requires Node 18 or higher diff --git a/.changeset/early-beds-obey.md b/.changeset/early-beds-obey.md deleted file mode 100644 index bac0cbcbf6..0000000000 --- a/.changeset/early-beds-obey.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"react-router-dom": major -"react-router": major ---- - -Remove `future.v7_startTransition` flag diff --git a/.changeset/eighty-dolls-juggle.md b/.changeset/eighty-dolls-juggle.md deleted file mode 100644 index 80416d4a76..0000000000 --- a/.changeset/eighty-dolls-juggle.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-router/dev": patch ---- - -Enable prerendering for resource routes diff --git a/.changeset/empty-glasses-dream.md b/.changeset/empty-glasses-dream.md deleted file mode 100644 index 0caa2812f1..0000000000 --- a/.changeset/empty-glasses-dream.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-router/dev": patch ---- - -chore: warn instead of error for min node version in CLI diff --git a/.changeset/expose-promises.md b/.changeset/expose-promises.md deleted file mode 100644 index 43bf5fbd63..0000000000 --- a/.changeset/expose-promises.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"react-router": major ---- - -- Expose the underlying router promises from the following APIs for compsition in React 19 APIs: - - `useNavigate()` - - `useSubmit` - - `useFetcher().load` - - `useFetcher().submit` - - `useRevalidator.revalidate` diff --git a/.changeset/fair-beans-design.md b/.changeset/fair-beans-design.md deleted file mode 100644 index a2d2fc494c..0000000000 --- a/.changeset/fair-beans-design.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-router/cloudflare": minor ---- - -The `@remix-run/cloudflare-workers` package has been deprecated. Remix consumers migrating to React Router should use the `@react-router/cloudflare` package directly. For guidance on how to use `@react-router/cloudflare` within a Cloudflare Workers context, refer to the Cloudflare Workers template. diff --git a/.changeset/fair-cheetahs-hope.md b/.changeset/fair-cheetahs-hope.md deleted file mode 100644 index e0503d468d..0000000000 --- a/.changeset/fair-cheetahs-hope.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"react-router-dom": major -"react-router": major ---- - -Remove `future.v7_normalizeFormMethod` future flag diff --git a/.changeset/fast-plums-peel.md b/.changeset/fast-plums-peel.md deleted file mode 100644 index a533cd425f..0000000000 --- a/.changeset/fast-plums-peel.md +++ /dev/null @@ -1,22 +0,0 @@ ---- -"@react-router/architect": major -"@react-router/cloudflare": major -"@react-router/node": major -"react-router": major ---- - -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: - -- `createCookie` -- `createCookieSessionStorage` -- `createMemorySessionStorage` -- `createSessionStorage` - -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` -- `createMemorySessionStorageFactory` diff --git a/.changeset/few-stingrays-explain.md b/.changeset/few-stingrays-explain.md deleted file mode 100644 index 55e3cbd2f8..0000000000 --- a/.changeset/few-stingrays-explain.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": patch ---- - -[REMOVE] Changeset to bump pre.4 release diff --git a/.changeset/five-cheetahs-press.md b/.changeset/five-cheetahs-press.md deleted file mode 100644 index b9c1dbd0f6..0000000000 --- a/.changeset/five-cheetahs-press.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-router/node": patch ---- - -Add createRequestListener to @react-router/node diff --git a/.changeset/fluffy-ducks-try.md b/.changeset/fluffy-ducks-try.md deleted file mode 100644 index 6761871eec..0000000000 --- a/.changeset/fluffy-ducks-try.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router-dom": major ---- - -Allow returning `undefined` from actions and loaders diff --git a/.changeset/four-needles-search.md b/.changeset/four-needles-search.md deleted file mode 100644 index f4552bd2c7..0000000000 --- a/.changeset/four-needles-search.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"integration": patch -"@react-router/dev": patch -"react-router": patch ---- - -chore: re-enable development warnings through a `development` exports condition. diff --git a/.changeset/fuzzy-worms-applaud.md b/.changeset/fuzzy-worms-applaud.md deleted file mode 100644 index 2bc32ba093..0000000000 --- a/.changeset/fuzzy-worms-applaud.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router-dom": patch ---- - -Memoize some `RouterProvider` internals to reduce uneccesary re-renders diff --git a/.changeset/gold-suns-march.md b/.changeset/gold-suns-march.md deleted file mode 100644 index b695f5b7f6..0000000000 --- a/.changeset/gold-suns-march.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -"react-router": major ---- - -Imports/Exports cleanup - -- Removed the following exports that were previously public API from `@remix-run/router` - - types - - `AgnosticDataIndexRouteObject` - - `AgnosticDataNonIndexRouteObject` - - `AgnosticDataRouteMatch` - - `AgnosticDataRouteObject` - - `AgnosticIndexRouteObject` - - `AgnosticNonIndexRouteObject` - - `AgnosticRouteMatch` - - `AgnosticRouteObject` - - `TrackedPromise` - - `unstable_AgnosticPatchRoutesOnMissFunction` - - `Action` -> exported as `NavigationType` via `react-router` - - `Router` exported as `DataRouter` to differentiate from RR's `` - - API - - `getToPathname` (`@private`) - - `joinPaths` (`@private`) - - `normalizePathname` (`@private`) - - `resolveTo` (`@private`) - - `stripBasename` (`@private`) - - `createBrowserHistory` -> in favor of `createBrowserRouter` - - `createHashHistory` -> in favor of `createHashRouter` - - `createMemoryHistory` -> in favor of `createMemoryRouter` - - `createRouter` - - `createStaticHandler` -> in favor of wrapper `createStaticHandler` in RR Dom - - `getStaticContextFromError` -- Removed the following exports that were previously public API from `react-router` - - `Hash` - - `Pathname` - - `Search` diff --git a/.changeset/kind-mirrors-hang.md b/.changeset/kind-mirrors-hang.md deleted file mode 100644 index 9754754a35..0000000000 --- a/.changeset/kind-mirrors-hang.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@react-router/node": patch -"react-router": patch ---- - -Remove unstable upload handler. diff --git a/.changeset/kind-timers-refuse.md b/.changeset/kind-timers-refuse.md deleted file mode 100644 index e9c18d5e17..0000000000 --- a/.changeset/kind-timers-refuse.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"react-router-dom": major -"@react-router/express": major -"react-router": major -"@react-router/serve": major -"@react-router/node": major -"@react-router/dev": major ---- - -update minimum node version to 18 diff --git a/.changeset/late-buckets-turn.md b/.changeset/late-buckets-turn.md deleted file mode 100644 index c3a23566ab..0000000000 --- a/.changeset/late-buckets-turn.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"react-router-dom": major -"react-router": major ---- - -Remove `future.v7_prependBasename` from the ionternalized `@remix-run/router` package diff --git a/.changeset/lemon-files-care.md b/.changeset/lemon-files-care.md deleted file mode 100644 index 6d584d2489..0000000000 --- a/.changeset/lemon-files-care.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-router/dev": patch ---- - -include root "react-dom" module for optimization diff --git a/.changeset/link-prefetching.md b/.changeset/link-prefetching.md deleted file mode 100644 index 0482a5c1b2..0000000000 --- a/.changeset/link-prefetching.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router-dom": minor ---- - -Add prefetching support to `Link`/`NavLink` when using Remix SSR diff --git a/.changeset/little-cooks-pull.md b/.changeset/little-cooks-pull.md deleted file mode 100644 index a221a5b2eb..0000000000 --- a/.changeset/little-cooks-pull.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": patch ---- - -[PRERELEASE] Fix typegen for routes with a client loader but no server loader diff --git a/.changeset/long-peas-doubt.md b/.changeset/long-peas-doubt.md deleted file mode 100644 index 67d9fa1952..0000000000 --- a/.changeset/long-peas-doubt.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -"react-router": major ---- - -Migrate Remix type generics to React Router - -- These generics are provided for Remix v2 migration purposes -- These generics and the APIs they exist on should be considered informally deprecated in favor of the new `Route.*` types -- Anyone migrating from React Router v6 should probably not leverage these new generics and should migrate straight to the `Route.*` types -- For React Router v6 users, these generics are new and should not impact your app, with one exception - - `useFetcher` previously had an optional generic (used primarily by Remix v2) that expected the data type - - This has been updated in v7 to expect the type of the function that generates the data (i.e., `typeof loader`/`typeof action`) - - Therefore, you should update your usages: - - ❌ `useFetcher()` - - ✅ `useFetcher()` diff --git a/.changeset/moody-kids-count.md b/.changeset/moody-kids-count.md deleted file mode 100644 index bac5e026db..0000000000 --- a/.changeset/moody-kids-count.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"react-router-dom": major -"react-router": major ---- - -Remove `future.v7_throwAbortReason` from internalized `@remix-run/router` package diff --git a/.changeset/nice-pillows-hunt.md b/.changeset/nice-pillows-hunt.md deleted file mode 100644 index cebc13fa69..0000000000 --- a/.changeset/nice-pillows-hunt.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@react-router/express": major -"@react-router/serve": major -"@react-router/node": major -"@react-router/dev": major -"react-router-dom": major -"react-router": major ---- - -Add `exports` field to all packages diff --git a/.changeset/nine-peas-change.md b/.changeset/nine-peas-change.md deleted file mode 100644 index 0c87673eb6..0000000000 --- a/.changeset/nine-peas-change.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"@react-router/node": patch -"react-router": patch ---- - -Remove unneeded dependency on @web3-storage/multipart-parser diff --git a/.changeset/nine-ravens-work.md b/.changeset/nine-ravens-work.md deleted file mode 100644 index faa55cd7fd..0000000000 --- a/.changeset/nine-ravens-work.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"react-router-dom": major -"@react-router/express": major -"react-router": major -"@react-router/serve": major -"@react-router/node": major -"@react-router/dev": major ---- - -node package no longer re-exports from react-router diff --git a/.changeset/odd-beds-behave.md b/.changeset/odd-beds-behave.md deleted file mode 100644 index 0a499191a9..0000000000 --- a/.changeset/odd-beds-behave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": major ---- - -renamed RemixContext to FrameworkContext diff --git a/.changeset/prerendering.md b/.changeset/prerendering.md deleted file mode 100644 index 8ddf01b043..0000000000 --- a/.changeset/prerendering.md +++ /dev/null @@ -1,26 +0,0 @@ ---- -"react-router": minor ---- - -- Add support for `prerender` config in the React Router vite plugin, to support existing SSG use-cases - - You can use the `prerender` config to pre-render your `.html` and `.data` files at build time and then serve them statically at runtime (either from a running server or a CDN) - - `prerender` can either be an array of string paths, or a function (sync or async) that returns an array of strings so that you can dynamically generate the paths by talking to your CMS, etc. - -```ts -// react-router.config.ts -import type { Config } from "@react-router/dev/config"; - -export default { - async prerender() { - let slugs = await fakeGetSlugsFromCms(); - // Prerender these paths into `.html` files at build time, and `.data` - // files if they have loaders - return ["/", "/about", ...slugs.map((slug) => `/product/${slug}`)]; - }, -} satisfies Config; - -async function fakeGetSlugsFromCms() { - await new Promise((r) => setTimeout(r, 1000)); - return ["shirt", "hat"]; -} -``` diff --git a/.changeset/purple-poems-laugh.md b/.changeset/purple-poems-laugh.md deleted file mode 100644 index b4501690e9..0000000000 --- a/.changeset/purple-poems-laugh.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": patch ---- - -Fix redirects returned from loaders/actions using `data()` diff --git a/.changeset/rare-plums-chew.md b/.changeset/rare-plums-chew.md deleted file mode 100644 index 7f071c8186..0000000000 --- a/.changeset/rare-plums-chew.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"@react-router/serve": patch -"@react-router/dev": patch -"react-router": patch ---- - -- [PRERELEASE] Fix `react-router-serve` handling of prerendered HTML files by removing the `redirect: false` option so it now falls back on the default `redirect: true` behavior of redirecting from `/folder` -> `/folder/` which will then pick up `/folder/index.html` from disk. See https://expressjs.com/en/resources/middleware/serve-static.html -- [PRERELEASE] Proxy prerendered loader data into prerender pass for HTML files to avoid double-invocations of the loader at build time diff --git a/.changeset/red-feet-shop.md b/.changeset/red-feet-shop.md deleted file mode 100644 index 3916605351..0000000000 --- a/.changeset/red-feet-shop.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"react-router": minor ---- - -[REMOVE] Allow returning undefined from loaders/actions part 2 - -- This is a follow up to #11680 which missed some of the Remix codepaths diff --git a/.changeset/red-olives-compare.md b/.changeset/red-olives-compare.md deleted file mode 100644 index 72c8383725..0000000000 --- a/.changeset/red-olives-compare.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"react-router-dom": major -"react-router": major ---- - -updates the minimum React version to 18 diff --git a/.changeset/remix-scroll-restoration.md b/.changeset/remix-scroll-restoration.md deleted file mode 100644 index 88e9a4eecc..0000000000 --- a/.changeset/remix-scroll-restoration.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router-dom": minor ---- - -Enhance `ScrollRestoration` so it can restore properly on an SSR'd document load diff --git a/.changeset/remove-build-end-public-path.md b/.changeset/remove-build-end-public-path.md deleted file mode 100644 index 56b396c863..0000000000 --- a/.changeset/remove-build-end-public-path.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-router/dev": major ---- - -For Remix consumers migrating to React Router who used the Vite plugin's `buildEnd` hook, the resolved `reactRouterConfig` object no longer contains a `publicPath` property since this belongs to Vite, not React Router. diff --git a/.changeset/remove-manifest-option.md b/.changeset/remove-manifest-option.md deleted file mode 100644 index 94173c6c9a..0000000000 --- a/.changeset/remove-manifest-option.md +++ /dev/null @@ -1,25 +0,0 @@ ---- -"@react-router/dev": major ---- - -For Remix consumers migrating to React Router, the Vite plugin's `manifest` option has been removed. - -The `manifest` option been superseded by the more powerful `buildEnd` hook since it's passed the `buildManifest` argument. You can still write the build manifest to disk if needed, but you'll most likely find it more convenient to write any logic depending on the build manifest within the `buildEnd` hook itself. - -If you were using the `manifest` option, you can replace it with a `buildEnd` hook that writes the manifest to disk like this: - -```ts -// react-router.config.ts -import type { Config } from "@react-router/dev/config"; -import { writeFile } from "node:fs/promises"; - -export default { - async buildEnd({ buildManifest }) { - await writeFile( - "build/manifest.json", - JSON.stringify(buildManifest, null, 2), - "utf-8" - ); - }, -} satisfies Config; -``` diff --git a/.changeset/remove-prefetchpagedescriptor.md b/.changeset/remove-prefetchpagedescriptor.md deleted file mode 100644 index c88fbf5aea..0000000000 --- a/.changeset/remove-prefetchpagedescriptor.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": major ---- - -PrefetchPageDescriptor replaced by PageLinkDescriptor diff --git a/.changeset/route-component-export-props.md b/.changeset/route-component-export-props.md deleted file mode 100644 index 8ed1ce9de5..0000000000 --- a/.changeset/route-component-export-props.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@react-router/dev": minor -"react-router": minor ---- - -Params, loader data, and action data as props for route component exports - -```tsx -export default function Component({ params, loaderData, actionData }) {} - -export function HydrateFallback({ params }) {} -export function ErrorBoundary({ params, loaderData, actionData }) {} -``` diff --git a/.changeset/router-provider-hydration.md b/.changeset/router-provider-hydration.md deleted file mode 100644 index 06b3a66ea7..0000000000 --- a/.changeset/router-provider-hydration.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router-dom": minor ---- - -Add built-in Remix-style hydration support to `RouterProvider`. When running from a Remix-SSR'd HTML payload with the proper `window` variables (`__remixContext`, `__remixManifest`, `__remixRouteModules`), you don't need to pass a `router` prop and `RouterProvider` will create the `router` for you internally. ([#11396](https://github.com/remix-run/react-router/pull/11396)) diff --git a/.changeset/serious-beds-approve.md b/.changeset/serious-beds-approve.md deleted file mode 100644 index 0e0611ba10..0000000000 --- a/.changeset/serious-beds-approve.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-router/dev": patch ---- - -resolve config directory relative to flat output file structure diff --git a/.changeset/serious-ravens-appear.md b/.changeset/serious-ravens-appear.md deleted file mode 100644 index 3de6ab93b1..0000000000 --- a/.changeset/serious-ravens-appear.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-router/dev": patch ---- - -if we are in SAP mode, always render the `index.html` for hydration diff --git a/.changeset/shiny-cameras-try.md b/.changeset/shiny-cameras-try.md deleted file mode 100644 index 6bec5dfd02..0000000000 --- a/.changeset/shiny-cameras-try.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"integration": patch -"@react-router/dev": patch -"react-router": patch ---- - -fix(react-router): (v7) fix static prerender of non-ascii characters diff --git a/.changeset/silly-papayas-trade.md b/.changeset/silly-papayas-trade.md deleted file mode 100644 index 4cd5ade31c..0000000000 --- a/.changeset/silly-papayas-trade.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": patch ---- - -[REMOVE] Rename RemixRouter->DataRouter diff --git a/.changeset/silver-cats-shave.md b/.changeset/silver-cats-shave.md deleted file mode 100644 index 698836f2c7..0000000000 --- a/.changeset/silver-cats-shave.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": patch ---- - -Replace `substr` with `substring` diff --git a/.changeset/sour-cycles-lie.md b/.changeset/sour-cycles-lie.md deleted file mode 100644 index 6cc890d54e..0000000000 --- a/.changeset/sour-cycles-lie.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"@react-router/dev": major -"react-router": major ---- - -- Consolidate types previously duplicated across `@remix-run/router`, `@remix-run/server-runtime`, and `@remix-run/react` now that they all live in `react-router` - - Examples: `LoaderFunction`, `LoaderFunctionArgs`, `ActionFunction`, `ActionFunctionArgs`, `DataFunctionArgs`, `RouteManifest`, `LinksFunction`, `Route`, `EntryRoute` - - The `RouteManifest` type used by the "remix" code is now slightly stricter because it is using the former `@remix-run/router` `RouteManifest` - - `Record -> Record` - - Removed `AppData` type in favor of inlining `unknown` in the few locations it was used - - Removed `ServerRuntimeMeta*` types in favor of the `Meta*` types they were duplicated from diff --git a/.changeset/strange-jeans-give.md b/.changeset/strange-jeans-give.md deleted file mode 100644 index a33c69d1a3..0000000000 --- a/.changeset/strange-jeans-give.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"react-router": patch ---- - -Remove the deprecated `json` utility - -- You can use [`Response.json`](https://developer.mozilla.org/en-US/docs/Web/API/Response/json_static) if you still need to construct JSON responses in your app diff --git a/.changeset/stupid-days-heal.md b/.changeset/stupid-days-heal.md deleted file mode 100644 index fecd283a9c..0000000000 --- a/.changeset/stupid-days-heal.md +++ /dev/null @@ -1,13 +0,0 @@ ---- -"@react-router/dev": major ---- - -Update default `isbot` version to v5 and drop support for `isbot@3` - -- If you have `isbot@4` or `isbot@5` in your `package.json`: - - You do not need to make any changes -- If you have `isbot@3` in your `package.json` and you have your own `entry.server.tsx` file in your repo - - You do not need to make any changes - - You can upgrade to `isbot@5` independent of the React Router v7 upgrade -- If you have `isbot@3` in your `package.json` and you do not have your own `entry.server.tsx` file in your repo - - You are using the internal default entry provided by React Router v7 and you will need to upgrade to `isbot@5` in your `package.json` diff --git a/.changeset/tall-mangos-add.md b/.changeset/tall-mangos-add.md deleted file mode 100644 index 7a960eeeaa..0000000000 --- a/.changeset/tall-mangos-add.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-router/dev": minor ---- - -Remove internal entry.server.spa.tsx implementation diff --git a/.changeset/tasty-penguins-live.md b/.changeset/tasty-penguins-live.md deleted file mode 100644 index 4ffae59f61..0000000000 --- a/.changeset/tasty-penguins-live.md +++ /dev/null @@ -1,11 +0,0 @@ ---- -"react-router-dom": major -"react-router": major ---- - -- Remove the `future.v7_partialHydration` flag - - This also removes the `` prop - - To migrate, move the `fallbackElement` to a `hydrateFallbackElement`/`HydrateFallback` on your root route - - Also worth nothing there is a related breaking changer with this future flag: - - Without `future.v7_partialHydration` (when using `fallbackElement`), `state.navigation` was populated during the initial load - - With `future.v7_partialHydration`, `state.navigation` remains in an `"idle"` state during the initial load diff --git a/.changeset/thin-nails-turn.md b/.changeset/thin-nails-turn.md deleted file mode 100644 index cfe12d7c0b..0000000000 --- a/.changeset/thin-nails-turn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": minor ---- - -Remove duplicate `RouterProvider` impliementations diff --git a/.changeset/three-seals-play.md b/.changeset/three-seals-play.md deleted file mode 100644 index 59ab4af832..0000000000 --- a/.changeset/three-seals-play.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@react-router/dev": minor ---- - -Add `prefix` route config helper to `@react-router/dev/routes` diff --git a/.changeset/tidy-clouds-lay.md b/.changeset/tidy-clouds-lay.md deleted file mode 100644 index 304c25d6f4..0000000000 --- a/.changeset/tidy-clouds-lay.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": major ---- - -Remove `v7_relativeSplatPath` future flag diff --git a/.changeset/tidy-pens-help.md b/.changeset/tidy-pens-help.md deleted file mode 100644 index 5db3b598d6..0000000000 --- a/.changeset/tidy-pens-help.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@react-router/express": major -"@react-router/node": major -"@react-router/dev": major -"react-router": major ---- - -Drop support for Node 18, update minimum Node vestion to 20 - -- Remove `installGlobals()` as this should no longer be necessary diff --git a/.changeset/tough-pens-brush.md b/.changeset/tough-pens-brush.md deleted file mode 100644 index 2927281795..0000000000 --- a/.changeset/tough-pens-brush.md +++ /dev/null @@ -1,10 +0,0 @@ ---- -"@react-router/serve": patch ---- - -Update `express.static` configurations to support prerendering - -- Assets in the `build/client/assets` folder are served as before, with a 1-year immutable `Cache-Control` header -- Static files outside of assets, such as pre-rendered `.html` and `.data` files are not served with a specific `Cache-Control` header -- `.data` files are served with `Content-Type: text/x-turbo` - - For some reason, when adding this via `express.static`, it seems to also add a `Cache-Control: public, max-age=0` to `.data` files diff --git a/.changeset/twelve-bees-sin.md b/.changeset/twelve-bees-sin.md deleted file mode 100644 index bc90c3289d..0000000000 --- a/.changeset/twelve-bees-sin.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": patch ---- - -Remove unneeded dependency on source-map diff --git a/.changeset/twelve-cheetahs-pretend.md b/.changeset/twelve-cheetahs-pretend.md deleted file mode 100644 index 0ec37aa33e..0000000000 --- a/.changeset/twelve-cheetahs-pretend.md +++ /dev/null @@ -1,8 +0,0 @@ ---- -"react-router": major ---- - -Remove remaining future flags - -- React Router `v7_skipActionErrorRevalidation` -- Remix `v3_fetcherPersist`, `v3_relativeSplatPath`, `v3_throwAbortReason` diff --git a/.changeset/twenty-carrots-yawn.md b/.changeset/twenty-carrots-yawn.md deleted file mode 100644 index 98c0abdedc..0000000000 --- a/.changeset/twenty-carrots-yawn.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": major ---- - -rename createRemixStub to createRoutesStub diff --git a/.changeset/two-countries-yell.md b/.changeset/two-countries-yell.md deleted file mode 100644 index de7d6d5098..0000000000 --- a/.changeset/two-countries-yell.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": major ---- - -Remove `@remix-run/router` deprecated `detectErrorBoundary` option in favor of `mapRouteProperties` diff --git a/.changeset/typesafety.md b/.changeset/typesafety.md deleted file mode 100644 index 7c437fe05f..0000000000 --- a/.changeset/typesafety.md +++ /dev/null @@ -1,39 +0,0 @@ ---- -"@react-router/dev": minor -"react-router": minor ---- - -### Typesafety improvements - -React Router now generates types for each of your route modules. -You can access those types by importing them from `./+types/`. -For example: - -```ts -// app/routes/product.tsx -import type { Route } from "./+types/product"; - -export function loader({ params }: Route.LoaderArgs) {} - -export default function Component({ loaderData }: Route.ComponentProps) {} -``` - -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 - -In the future, we plan to add types for the rest of the route module exports: `meta`, `links`, `headers`, `shouldRevalidate`, etc. -We also plan to generate types for typesafe `Link`s: - -```tsx - -// ^^^^^^^^^^^^^ ^^^^^^^^^ -// typesafe `to` and `params` based on the available routes in your app -``` - -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/.changeset/violet-beds-swim.md b/.changeset/violet-beds-swim.md deleted file mode 100644 index 1acd1fdaa0..0000000000 --- a/.changeset/violet-beds-swim.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": minor ---- - -Stabilize `unstable_dataStrategy` diff --git a/.changeset/vite-manifest-location.md b/.changeset/vite-manifest-location.md deleted file mode 100644 index 31fdb73e0d..0000000000 --- a/.changeset/vite-manifest-location.md +++ /dev/null @@ -1,7 +0,0 @@ ---- -"@react-router/dev": major ---- - -For Remix consumers migrating to React Router, Vite manifests (i.e. `.vite/manifest.json`) are now written within each build subdirectory, e.g. `build/client/.vite/manifest.json` and `build/server/.vite/manifest.json` instead of `build/.vite/client-manifest.json` and `build/.vite/server-manifest.json`. This means that the build output is now much closer to what you'd expect from a typical Vite project. - -Originally the Remix Vite plugin moved all Vite manifests to a root-level `build/.vite` directory to avoid accidentally serving them in production, particularly from the client build. This was later improved with additional logic that deleted these Vite manifest files at the end of the build process unless Vite's `build.manifest` had been enabled within the app's Vite config. This greatly reduced the risk of accidentally serving the Vite manifests in production since they're only present when explicitly asked for. As a result, we can now assume that consumers will know that they need to manage these additional files themselves, and React Router can safely generate a more standard Vite build output. diff --git a/.changeset/warm-melons-shop.md b/.changeset/warm-melons-shop.md deleted file mode 100644 index 4d73f59df9..0000000000 --- a/.changeset/warm-melons-shop.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": minor ---- - -Stabilize `unstable_patchRoutesOnNavigation` diff --git a/.changeset/weak-goats-cross.md b/.changeset/weak-goats-cross.md deleted file mode 100644 index b7792dd3a5..0000000000 --- a/.changeset/weak-goats-cross.md +++ /dev/null @@ -1,12 +0,0 @@ ---- -"react-router": major ---- - -Add `react-router/dom` subpath export to properly enable `react-dom` as an optional `peerDependency` - -- This ensures that we don't blindly `import ReactDOM from "react-dom"` in `` in order to access `ReactDOM.flushSync()`, since that would break `createMemoryRouter` use cases in non-DOM environments -- DOM environments should import from `react-router/dom` to get the proper component that makes `ReactDOM.flushSync()` available: - - If you are using the Vite plugin, use this in your `entry.client.tsx`: - - `import { HydratedRouter } from 'react-router/dom'` - - If you are not using the Vite plugin and are manually calling `createBrowserRouter`/`createHashRouter`: - - `import { RouterProvider } from "react-router/dom"` diff --git a/.changeset/weak-otters-dance.md b/.changeset/weak-otters-dance.md deleted file mode 100644 index fbe5d5ad2b..0000000000 --- a/.changeset/weak-otters-dance.md +++ /dev/null @@ -1,6 +0,0 @@ ---- -"react-router-dom": major -"react-router": major ---- - -Remove `future.v7_fetcherPersist` flag diff --git a/.changeset/wet-actors-act.md b/.changeset/wet-actors-act.md deleted file mode 100644 index 0171c0f48e..0000000000 --- a/.changeset/wet-actors-act.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"react-router": major ---- - -Update `cookie` dependency to `^1.0.1` - please see the [release notes](https://github.com/jshttp/cookie/releases) for any breaking changes diff --git a/CHANGELOG.md b/CHANGELOG.md index 6e2a02e689..5ab1d6f577 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -13,193 +13,217 @@ We manage release notes in this file instead of the paginated Github Releases Pa Table of Contents - [React Router Releases](#react-router-releases) - - [v6.28.0](#v6280) - - [What's Changed](#whats-changed) + - [v7.0.0](#v700) + - [Breaking Changes](#breaking-changes) + - [Package Restructuring](#package-restructuring) + - [Removed Adapter Re-exports](#removed-adapter-re-exports) + - [Removed APIs](#removed-apis) + - [Minimum Versions](#minimum-versions) + - [Adopted Future Flag Behaviors](#adopted-future-flag-behaviors) + - [Vite Compiler](#vite-compiler) + - [Exposed Router Promises](#exposed-router-promises) + - [Other Notable Changes](#other-notable-changes) + - [`routes.ts`](#routests) + - [Typesafety improvements](#typesafety-improvements) + - [Setup](#setup) + - [`typegen` command](#typegen-command) + - [TypeScript plugin](#typescript-plugin) + - [VSCode](#vscode) + - [Troubleshooting](#troubleshooting) + - [Prerendering](#prerendering) + - [Major Changes (`react-router`)](#major-changes-react-router) + - [Major Changes (`@react-router/*`)](#major-changes-react-router-1) - [Minor Changes](#minor-changes) - [Patch Changes](#patch-changes) + - [Changes by Package](#changes-by-package) +- [**Full Changelog**: `v6.28.0...v7.0.0`](#full-changelog-v6280v700) + - [v6.28.0](#v6280) + - [What's Changed](#whats-changed) + - [Minor Changes](#minor-changes-1) + - [Patch Changes](#patch-changes-1) - [v6.27.0](#v6270) - [What's Changed](#whats-changed-1) - [Stabilized APIs](#stabilized-apis) - - [Minor Changes](#minor-changes-1) - - [Patch Changes](#patch-changes-1) - - [v6.26.2](#v6262) + - [Minor Changes](#minor-changes-2) - [Patch Changes](#patch-changes-2) - - [v6.26.1](#v6261) + - [v6.26.2](#v6262) - [Patch Changes](#patch-changes-3) - - [v6.26.0](#v6260) - - [Minor Changes](#minor-changes-2) + - [v6.26.1](#v6261) - [Patch Changes](#patch-changes-4) - - [v6.25.1](#v6251) + - [v6.26.0](#v6260) + - [Minor Changes](#minor-changes-3) - [Patch Changes](#patch-changes-5) + - [v6.25.1](#v6251) + - [Patch Changes](#patch-changes-6) - [v6.25.0](#v6250) - [What's Changed](#whats-changed-2) - [Stabilized `v7_skipActionErrorRevalidation`](#stabilized-v7_skipactionerrorrevalidation) - - [Minor Changes](#minor-changes-3) - - [Patch Changes](#patch-changes-6) - - [v6.24.1](#v6241) + - [Minor Changes](#minor-changes-4) - [Patch Changes](#patch-changes-7) + - [v6.24.1](#v6241) + - [Patch Changes](#patch-changes-8) - [v6.24.0](#v6240) - [What's Changed](#whats-changed-3) - [Lazy Route Discovery (a.k.a. "Fog of War")](#lazy-route-discovery-aka-fog-of-war) - - [Minor Changes](#minor-changes-4) - - [Patch Changes](#patch-changes-8) - - [v6.23.1](#v6231) + - [Minor Changes](#minor-changes-5) - [Patch Changes](#patch-changes-9) + - [v6.23.1](#v6231) + - [Patch Changes](#patch-changes-10) - [v6.23.0](#v6230) - [What's Changed](#whats-changed-4) - [Data Strategy (unstable)](#data-strategy-unstable) - [Skip Action Error Revalidation (unstable)](#skip-action-error-revalidation-unstable) - - [Minor Changes](#minor-changes-5) + - [Minor Changes](#minor-changes-6) - [v6.22.3](#v6223) - - [Patch Changes](#patch-changes-10) - - [v6.22.2](#v6222) - [Patch Changes](#patch-changes-11) - - [v6.22.1](#v6221) + - [v6.22.2](#v6222) - [Patch Changes](#patch-changes-12) + - [v6.22.1](#v6221) + - [Patch Changes](#patch-changes-13) - [v6.22.0](#v6220) - [What's Changed](#whats-changed-5) - [Core Web Vitals Technology Report Flag](#core-web-vitals-technology-report-flag) - - [Minor Changes](#minor-changes-6) - - [Patch Changes](#patch-changes-13) - - [v6.21.3](#v6213) + - [Minor Changes](#minor-changes-7) - [Patch Changes](#patch-changes-14) - - [v6.21.2](#v6212) + - [v6.21.3](#v6213) - [Patch Changes](#patch-changes-15) - - [v6.21.1](#v6211) + - [v6.21.2](#v6212) - [Patch Changes](#patch-changes-16) + - [v6.21.1](#v6211) + - [Patch Changes](#patch-changes-17) - [v6.21.0](#v6210) - [What's Changed](#whats-changed-6) - [`future.v7_relativeSplatPath`](#futurev7_relativesplatpath) - [Partial Hydration](#partial-hydration) - - [Minor Changes](#minor-changes-7) - - [Patch Changes](#patch-changes-17) - - [v6.20.1](#v6201) - - [Patch Changes](#patch-changes-18) - - [v6.20.0](#v6200) - [Minor Changes](#minor-changes-8) + - [Patch Changes](#patch-changes-18) + - [v6.20.1](#v6201) - [Patch Changes](#patch-changes-19) + - [v6.20.0](#v6200) + - [Minor Changes](#minor-changes-9) + - [Patch Changes](#patch-changes-20) - [v6.19.0](#v6190) - [What's Changed](#whats-changed-7) - [`unstable_flushSync` API](#unstable_flushsync-api) - - [Minor Changes](#minor-changes-9) - - [Patch Changes](#patch-changes-20) + - [Minor Changes](#minor-changes-10) + - [Patch Changes](#patch-changes-21) - [v6.18.0](#v6180) - [What's Changed](#whats-changed-8) - [New Fetcher APIs](#new-fetcher-apis) - [Persistence Future Flag (`future.v7_fetcherPersist`)](#persistence-future-flag-futurev7_fetcherpersist) - - [Minor Changes](#minor-changes-10) - - [Patch Changes](#patch-changes-21) + - [Minor Changes](#minor-changes-11) + - [Patch Changes](#patch-changes-22) - [v6.17.0](#v6170) - [What's Changed](#whats-changed-9) - [View Transitions 🚀](#view-transitions-) - - [Minor Changes](#minor-changes-11) - - [Patch Changes](#patch-changes-22) - - [v6.16.0](#v6160) - [Minor Changes](#minor-changes-12) - [Patch Changes](#patch-changes-23) - - [v6.15.0](#v6150) + - [v6.16.0](#v6160) - [Minor Changes](#minor-changes-13) - [Patch Changes](#patch-changes-24) - - [v6.14.2](#v6142) + - [v6.15.0](#v6150) + - [Minor Changes](#minor-changes-14) - [Patch Changes](#patch-changes-25) - - [v6.14.1](#v6141) + - [v6.14.2](#v6142) - [Patch Changes](#patch-changes-26) + - [v6.14.1](#v6141) + - [Patch Changes](#patch-changes-27) - [v6.14.0](#v6140) - [What's Changed](#whats-changed-10) - [JSON/Text Submissions](#jsontext-submissions) - - [Minor Changes](#minor-changes-14) - - [Patch Changes](#patch-changes-27) + - [Minor Changes](#minor-changes-15) + - [Patch Changes](#patch-changes-28) - [v6.13.0](#v6130) - [What's Changed](#whats-changed-11) - [`future.v7_startTransition`](#futurev7_starttransition) - - [Minor Changes](#minor-changes-15) - - [Patch Changes](#patch-changes-28) - - [v6.12.1](#v6121) + - [Minor Changes](#minor-changes-16) - [Patch Changes](#patch-changes-29) + - [v6.12.1](#v6121) + - [Patch Changes](#patch-changes-30) - [v6.12.0](#v6120) - [What's Changed](#whats-changed-12) - [`React.startTransition` support](#reactstarttransition-support) - - [Minor Changes](#minor-changes-16) - - [Patch Changes](#patch-changes-30) - - [v6.11.2](#v6112) + - [Minor Changes](#minor-changes-17) - [Patch Changes](#patch-changes-31) - - [v6.11.1](#v6111) + - [v6.11.2](#v6112) - [Patch Changes](#patch-changes-32) - - [v6.11.0](#v6110) - - [Minor Changes](#minor-changes-17) + - [v6.11.1](#v6111) - [Patch Changes](#patch-changes-33) + - [v6.11.0](#v6110) + - [Minor Changes](#minor-changes-18) + - [Patch Changes](#patch-changes-34) - [v6.10.0](#v6100) - [What's Changed](#whats-changed-13) - - [Minor Changes](#minor-changes-18) + - [Minor Changes](#minor-changes-19) - [`future.v7_normalizeFormMethod`](#futurev7_normalizeformmethod) - - [Patch Changes](#patch-changes-34) + - [Patch Changes](#patch-changes-35) - [v6.9.0](#v690) - [What's Changed](#whats-changed-14) - [`Component`/`ErrorBoundary` route properties](#componenterrorboundary-route-properties) - [Introducing Lazy Route Modules](#introducing-lazy-route-modules) - - [Minor Changes](#minor-changes-19) - - [Patch Changes](#patch-changes-35) - - [v6.8.2](#v682) + - [Minor Changes](#minor-changes-20) - [Patch Changes](#patch-changes-36) - - [v6.8.1](#v681) + - [v6.8.2](#v682) - [Patch Changes](#patch-changes-37) - - [v6.8.0](#v680) - - [Minor Changes](#minor-changes-20) + - [v6.8.1](#v681) - [Patch Changes](#patch-changes-38) - - [v6.7.0](#v670) + - [v6.8.0](#v680) - [Minor Changes](#minor-changes-21) - [Patch Changes](#patch-changes-39) - - [v6.6.2](#v662) + - [v6.7.0](#v670) + - [Minor Changes](#minor-changes-22) - [Patch Changes](#patch-changes-40) - - [v6.6.1](#v661) + - [v6.6.2](#v662) - [Patch Changes](#patch-changes-41) + - [v6.6.1](#v661) + - [Patch Changes](#patch-changes-42) - [v6.6.0](#v660) - [What's Changed](#whats-changed-15) - - [Minor Changes](#minor-changes-22) - - [Patch Changes](#patch-changes-42) - - [v6.5.0](#v650) - - [What's Changed](#whats-changed-16) - [Minor Changes](#minor-changes-23) - [Patch Changes](#patch-changes-43) - - [v6.4.5](#v645) + - [v6.5.0](#v650) + - [What's Changed](#whats-changed-16) + - [Minor Changes](#minor-changes-24) - [Patch Changes](#patch-changes-44) - - [v6.4.4](#v644) + - [v6.4.5](#v645) - [Patch Changes](#patch-changes-45) - - [v6.4.3](#v643) + - [v6.4.4](#v644) - [Patch Changes](#patch-changes-46) - - [v6.4.2](#v642) + - [v6.4.3](#v643) - [Patch Changes](#patch-changes-47) - - [v6.4.1](#v641) + - [v6.4.2](#v642) - [Patch Changes](#patch-changes-48) + - [v6.4.1](#v641) + - [Patch Changes](#patch-changes-49) - [v6.4.0](#v640) - [What's Changed](#whats-changed-17) - [Remix Data APIs](#remix-data-apis) - - [Patch Changes](#patch-changes-49) + - [Patch Changes](#patch-changes-50) - [v6.3.0](#v630) - - [Minor Changes](#minor-changes-24) + - [Minor Changes](#minor-changes-25) - [v6.2.2](#v622) - - [Patch Changes](#patch-changes-50) - - [v6.2.1](#v621) - [Patch Changes](#patch-changes-51) - - [v6.2.0](#v620) - - [Minor Changes](#minor-changes-25) + - [v6.2.1](#v621) - [Patch Changes](#patch-changes-52) - - [v6.1.1](#v611) - - [Patch Changes](#patch-changes-53) - - [v6.1.0](#v610) + - [v6.2.0](#v620) - [Minor Changes](#minor-changes-26) + - [Patch Changes](#patch-changes-53) + - [v6.1.1](#v611) - [Patch Changes](#patch-changes-54) - - [v6.0.2](#v602) + - [v6.1.0](#v610) + - [Minor Changes](#minor-changes-27) - [Patch Changes](#patch-changes-55) - - [v6.0.1](#v601) + - [v6.0.2](#v602) - [Patch Changes](#patch-changes-56) + - [v6.0.1](#v601) + - [Patch Changes](#patch-changes-57) - [v6.0.0](#v600) +## v7.0.0 + +Date: 2024-11-21 + +### Breaking Changes + +#### Package Restructuring + +- The `react-router-dom`, `@remix-run/react`, `@remix-run/server-runtime`, and `@remix-run/router` have been collapsed into the `react-router` package + - To ease migration, `react-router-dom` is still published in v7 as a re-export of everything from `react-router` +- The `@remix-run/cloudflare-pages` and `@remix-run/cloudflare-workers` have been collapsed into `@react-router/cloudflare` package` +- The `react-router-dom-v5-compat` and `react-router-native` packages are removed starting with v7 + +#### Removed Adapter Re-exports + +Remix v2 used to re-export all common `@remix-run/server-runtime` APIs through the various runtime packages (`node`, `cloudflare`, `deno`) so that you wouldn't need an additional `@remix-run/server-runtime` dependency in your `package.json`. With the collapsing of packages into `react-router`, these common APIs are now no longer re-exported through the runtime adapters. You should import all common APIs from `react-router`, and only import runtime-specific APIs from the runtime packages: + +```jsx +// Runtime-specific APIs +import { createFileSessionStorage } from "@react-router/node"; +// Runtime-agnostic APIs +import { redirect, useLoaderData } from "react-router"; +``` + +#### Removed APIs + +The following APIs have been removed in React Router v7: + +- `json` +- `defer` +- `unstable_composeUploadHandlers` +- `unstable_createMemoryUploadHandler` +- `unstable_parseMultipartFormData` + +#### Minimum Versions + +React Router v7 requires the following minimum versions: + +- `node@20` + - React Router no longer provides an `installGlobals` method to [polyfill](https://reactrouter.com/dev/guides/deploying/custom-node#polyfilling-fetch) the `fetch` API +- `react@18`, `react-dom@18` + +#### Adopted Future Flag Behaviors + +Remix and React Router follow an [API Development Strategy](https://reactrouter.com/en/main/guides/api-development-strategy) leveraging "Future Flags" to avoid introducing a slew of breaking changes in a major release. Instead, breaking changes are introduce din minor releases behind a flag, allowing users to opt-in at their convenience. In the next major release, all future flag behaviors become the default behavior. + +The following previously flagged behaviors are now the default in React Router v7: + +- [React Router v6 flags](https://reactrouter.com/en/v6/upgrading/future) + - `future.v7_relativeSplatPath` + - `future.v7_startTransition` + - `future.v7_fetcherPersist` + - `future.v7_normalizeFormMethod` + - `future.v7_partialHydration` + - `future.v7_skipActionStatusRevalidation` +- [Remix v2 flags](https://remix.run/docs/en/v2/start/future-flags) + - `future.v3_fetcherPersist` + - `future.v3_relativeSplatPath` + - `future.v3_throwAbortReason` + - `future.v3_singleFetch` + - `future.v3_lazyRouteDiscovery` + - `future.v3_optimizeDeps` + +#### Vite Compiler + +The [Remix Vite plugin](https://remix.run/docs/en/2.12.1/start/future-flags#vite-plugin) is the proper way to build full-stack SSR apps using React Router v7. The former `esbuild`-based compiler is no longer available. + +**Renamed `vitePlugin` and `cloudflareDevProxyVitePlugin`** + +For Remix consumers migrating to React Router, the `vitePlugin` and `cloudflareDevProxyVitePlugin` exports have been renamed and moved ([#11904](https://github.com/remix-run/react-router/pull/11904)) + +```diff +-import { +- vitePlugin as remix, +- cloudflareDevProxyVitePlugin, +-} from "@remix/dev"; + ++import { reactRouter } from "@react-router/dev/vite"; ++import { cloudflareDevProxy } from "@react-router/dev/vite/cloudflare"; +``` + +**Removed Vite Plugin `manifest` option** + +For Remix consumers migrating to React Router, the Vite plugin's `manifest` option has been removed. The `manifest` option been superseded by the more powerful `buildEnd` hook since it's passed the `buildManifest` argument. You can still write the build manifest to disk if needed, but you'll most likely find it more convenient to write any logic depending on the build manifest within the `buildEnd` hook itself. ([#11573](https://github.com/remix-run/react-router/pull/11573)) + +If you were using the `manifest` option, you can replace it with a `buildEnd` hook that writes the manifest to disk like this: + +```js +import { reactRouter } from "@react-router/dev/vite"; +import { writeFile } from "node:fs/promises"; + +export default { + plugins: [ + reactRouter({ + async buildEnd({ buildManifest }) { + await writeFile( + "build/manifest.json", + JSON.stringify(buildManifest, null, 2), + "utf-8" + ); + }, + }), + ], +}; +``` + +#### Exposed Router Promises + +Because React 19 will have first-class support for handling promises in the render pass (via `React.use` and `useAction`), we are now comfortable exposing the promises for the APIs that previously returned `undefined`: + +- `useNavigate()` +- `useSubmit()` +- `useFetcher().load` +- `useFetcher().submit` +- `useRevalidator().revalidate()` + +### Other Notable Changes + +#### `routes.ts` + +When using the React Router Vite plugin, routes are defined in `app/routes.ts`. Route config is exported via the `routes` export, conforming to the `RouteConfig` type. Route helper functions `route`, `index`, and `layout` are provided to make declarative type-safe route definitions easier. + +```ts +// app/routes.ts +import { + type RouteConfig, + route, + index, + layout, +} from "@react-router/dev/routes"; + +export const routes: RouteConfig = [ + index("./home.tsx"), + route("about", "./about.tsx"), + + layout("./auth/layout.tsx", [ + route("login", "./auth/login.tsx"), + route("register", "./auth/register.tsx"), + ]), + + route("concerts", [ + index("./concerts/home.tsx"), + route(":city", "./concerts/city.tsx"), + route("trending", "./concerts/trending.tsx"), + ]), +]; +``` + +For Remix consumers migrating to React Router, you can still configure file system routing within `routes.ts` using the `@react-router/fs-routes` package. A minimal route config that reproduces the default Remix setup looks like this: + +```ts +// app/routes.ts +import { type RouteConfig } from "@react-router/dev/routes"; +import { flatRoutes } from "@react-router/fs-routes"; + +export const routes: RouteConfig = flatRoutes(); +``` + +If you want to migrate from file system routing to config-based routes, you can mix and match approaches by spreading the results of the async `flatRoutes` function into the array of config-based routes. + +```ts +// app/routes.ts +import { type RouteConfig, route } from "@react-router/dev/routes"; +import { flatRoutes } from "@react-router/fs-routes"; + +export const routes: RouteConfig = [ + // Example config-based route: + route("/hello", "./routes/hello.tsx"), + + // File system routes scoped to a different directory: + ...(await flatRoutes({ + rootDirectory: "fs-routes", + })), +]; +``` + +If you were using Remix's `routes` option to use alternative file system routing conventions, you can adapt these to the new `RouteConfig` format using `@react-router/remix-config-routes-adapter`. + +For example, if you were using [Remix v1 route conventions](https://remix.run/docs/en/1.19.3/file-conventions/routes-files) in Remix v2, you can combine `@react-router/remix-config-routes-adapter` with `@remix-run/v1-route-convention` to adapt this to React Router: + +```ts +// app/routes.ts +import { type RouteConfig } from "@react-router/dev/routes"; +import { remixConfigRoutes } from "@react-router/remix-config-routes-adapter"; +import { createRoutesFromFolders } from "@remix-run/v1-route-convention"; + +export const routes: RouteConfig = remixConfigRoutes(async (defineRoutes) => { + return createRoutesFromFolders(defineRoutes, { + ignoredFilePatterns: ["**/.*", "**/*.css"], + }); +}); +``` + +Also note that, if you were using Remix's `routes` option to define config-based routes, you can also adapt these to the new `RouteConfig` format using `@react-router/remix-config-routes-adapter` with minimal code changes. While this makes for a fast migration path, we recommend migrating any config-based routes from Remix to the new `RouteConfig` format since it's a fairly straightforward migration. + +```diff +// app/routes.ts +-import { type RouteConfig } from "@react-router/dev/routes"; ++import { type RouteConfig, route } from "@react-router/dev/routes"; +-import { remixConfigRoutes } from "@react-router/remix-config-routes-adapter"; + +-export const routes: RouteConfig = remixConfigRoutes(async (defineRoutes) => { +- defineRoutes((route) => { +- route("/parent", "./routes/parent.tsx", () => [ +- route("/child", "./routes/child.tsx"), +- ]); +- }); +-}); ++export const routes: RouteConfig = [ ++ route("/parent", "./routes/parent.tsx", [ ++ route("/child", "./routes/child.tsx"), ++ ]), ++]; +``` + +#### Typesafety improvements + +React Router now generates types for each of your route modules and passes typed props to route module component exports ([#11961](https://github.com/remix-run/react-router/pull/11961), [#12019](https://github.com/remix-run/react-router/pull/12019)). You can access those types by importing them from `./+types.`. + +For example: + +```ts +// app/routes/product.tsx +import type * as Route from "./+types.product"; + +export function loader({ params }: Route.LoaderArgs) {} + +export default function Component({ loaderData }: Route.ComponentProps) {} +``` + +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 + +These types are then used to create types for route export args and props: + +- `LoaderArgs` +- `ClientLoaderArgs` +- `ActionArgs` +- `ClientActionArgs` +- `HydrateFallbackProps` +- `ComponentProps` (for the `default` export) +- `ErrorBoundaryProps` + +In the future, we plan to add types for the rest of the route module exports: `meta`, `links`, `headers`, `shouldRevalidate`, etc. + +We also plan to generate types for typesafe `Link`s: + +```tsx + +// ^^^^^^^^^^^^^ ^^^^^^^^^ +// typesafe `to` and `params` based on the available routes in your app +``` + +##### Setup + +React Router will generate types into a `.react-router/` directory at the root of your app. This directory is fully managed by React Router and is derived based on your route config (`routes.ts`). + +👉 **Add `.react-router/` to `.gitignore`** + +```txt +.react-router +``` + +You should also ensure that generated types for routes are always present before running typechecking, especially for running typechecking in CI. + +👉 **Add `react-router typegen` to your `typecheck` command in `package.json`** + +```json +{ + "scripts": { + "typecheck": "react-router typegen && tsc" + } +} +``` + +To get TypeScript to use those generated types, you'll need to add them to `include` in `tsconfig.json`. And to be able to import them as if they files next to your route modules, you'll also need to configure `rootDirs`. + +👉 **Configure `tsconfig.json` for generated types** + +```json +{ + "include": [".react-router/types/**/*"], + "compilerOptions": { + "rootDirs": [".", "./.react-router/types"] + } +} +``` + +##### `typegen` command + +You can manually generate types with the new `typegen` command: + +```sh +react-router typegen +``` + +However, manual type generation is tedious and types can get out of sync quickly if you ever forget to run `typegen`. Instead, we recommend that you setup our new TypeScript plugin which will automatically generate fresh types whenever routes change. That way, you'll always have up-to-date types. + +##### TypeScript plugin + +To get automatic type generation, you can use our new TypeScript plugin. + +👉 **Add the TypeScript plugin to `tsconfig.json`** + +```json +{ + "compilerOptions": { + "plugins": [{ "name": "@react-router/dev" }] + } +} +``` + +We plan to add some other goodies to our TypeScript plugin soon, including: + +- Automatic `jsdoc` for route exports that include links to official docs +- Autocomplete for route exports +- Warnings for non-HMR compliant exports + +###### VSCode + +TypeScript looks for plugins registered in `tsconfig.json` in the local `node_modules/`, +but VSCode ships with its own copy of TypeScript that is installed outside of your project. +For TypeScript plugins to work, you'll need to tell VSCode to use the local workspace version of TypeScript. + +👉 **Ensure that VSCode is using the workspace version of TypeScript** + +This should already be set up for you by a `.vscode/settings.json`: + +```json +{ + "typescript.tsdk": "node_modules/typescript/lib" +} +``` + +Alternatively, you can open up any TypeScript file and use CMD+SHIFT+P to find `Select TypeScript Version` and then select `Use Workspace Version`. You may need to quit VSCode and reopen it for this setting to take effect. + +###### Troubleshooting + +In VSCode, open up any TypeScript file in your project and then use CMD+SHIFT+P to select `Open TS Server log`. There should be a log for `[react-router] setup` that indicates that the plugin was resolved correctly. Then look for any errors in the log. + +#### Prerendering + +React Router v7 includes a new `prerender` config in the vite plugin to support SSG use-cases. This will pre-render your `.html` and `.data` files at build time and so you can serve them statically at runtime from a running server or a CDN ([#11539](https://github.com/remix-run/react-router/pull/11539)) + +```ts +export default defineConfig({ + plugins: [ + reactRouter({ + async prerender({ getStaticPaths }) { + let slugs = await fakeGetSlugsFromCms(); + return [ + ...getStaticPaths(), + ...slugs.map((slug) => `/product/${slug}`), + ]; + }, + }), + tsconfigPaths(), + ], +}); + +async function fakeGetSlugsFromCms() { + await new Promise((r) => setTimeout(r, 1000)); + return ["shirt", "hat"]; +} +``` + +### Major Changes (`react-router`) + +- Remove the original `defer` implementation in favor of using raw promises via single fetch and `turbo-stream` ([#11744](https://github.com/remix-run/react-router/pull/11744)) + - This removes these exports from React Router: + - `defer` + - `AbortedDeferredError` + - `type TypedDeferredData` + - `UNSAFE_DeferredData` + - `UNSAFE_DEFERRED_SYMBOL` +- Collapse packages into `react-router`([#11505](https://github.com/remix-run/react-router/pull/11505)) + - `@remix-run/router` + - `react-router-dom` + - `@remix-run/server-runtime` + - `@remix-run/testing` + - As a note, the `react-router-dom` package is maintained to ease adoption but it simply re-exports all APIs from `react-router` +- Drop support for Node 16, React Router SSR now requires Node 18 or higher ([#11391](https://github.com/remix-run/react-router/pull/11391), [#11690](https://github.com/remix-run/react-router/pull/11690)) +- Remove `future.v7_startTransition` flag ([#11696](https://github.com/remix-run/react-router/pull/11696)) +- Expose the underlying router promises from the following APIs for composition in React 19 APIs: ([#11521](https://github.com/remix-run/react-router/pull/11521)) +- Remove `future.v7_normalizeFormMethod` future flag ([#11697](https://github.com/remix-run/react-router/pull/11697)) +- Imports/Exports cleanup ([#11840](https://github.com/remix-run/react-router/pull/11840)) + - Removed the following exports that were previously public API from `@remix-run/router` + - types + - `AgnosticDataIndexRouteObject` + - `AgnosticDataNonIndexRouteObject` + - `AgnosticDataRouteMatch` + - `AgnosticDataRouteObject` + - `AgnosticIndexRouteObject` + - `AgnosticNonIndexRouteObject` + - `AgnosticRouteMatch` + - `AgnosticRouteObject` + - `TrackedPromise` + - `unstable_AgnosticPatchRoutesOnMissFunction` + - `Action` -> exported as `NavigationType` via `react-router` + - `Router` exported as `RemixRouter` to differentiate from RR's `` + - API + - `getToPathname` (`@private`) + - `joinPaths` (`@private`) + - `normalizePathname` (`@private`) + - `resolveTo` (`@private`) + - `stripBasename` (`@private`) + - `createBrowserHistory` -> in favor of `createBrowserRouter` + - `createHashHistory` -> in favor of `createHashRouter` + - `createMemoryHistory` -> in favor of `createMemoryRouter` + - `createRouter` + - `createStaticHandler` -> in favor of wrapper `createStaticHandler` in RR Dom + - `getStaticContextFromError` + - Removed the following exports that were previously public API from `react-router` + - `Hash` + - `Pathname` + - `Search` +- Remove `future.v7_prependBasename` from the internalized `@remix-run/router` package ([#11726](https://github.com/remix-run/react-router/pull/11726)) +- Remove `future.v7_throwAbortReason` from internalized `@remix-run/router` package ([#11728](https://github.com/remix-run/react-router/pull/11728)) +- Add `exports` field to all packages ([#11675](https://github.com/remix-run/react-router/pull/11675)) +- Renamed `RemixContext` to `FrameworkContext` ([#11705](https://github.com/remix-run/react-router/pull/11705)) +- Update the minimum React version to 18 ([#11689](https://github.com/remix-run/react-router/pull/11689)) +- `PrefetchPageDescriptor` replaced by `PageLinkDescriptor` ([#11960](https://github.com/remix-run/react-router/pull/11960)) +- Remove the `future.v7_partialHydration` flag ([#11725](https://github.com/remix-run/react-router/pull/11725)) + - This also removes the `` prop + - To migrate, move the `fallbackElement` to a `hydrateFallbackElement`/`HydrateFallback` on your root route + - Also worth nothing there is a related breaking changer with this future flag: + - Without `future.v7_partialHydration` (when using `fallbackElement`), `state.navigation` was populated during the initial load + - With `future.v7_partialHydration`, `state.navigation` remains in an `"idle"` state during the initial load +- Remove `future.v7_relativeSplatPath` future flag ([#11695](https://github.com/remix-run/react-router/pull/11695)) +- Remove remaining future flags ([#11820](https://github.com/remix-run/react-router/pull/11820)) + - React Router `v7_skipActionErrorRevalidation` + - Remix `v3_fetcherPersist`, `v3_relativeSplatPath`, `v3_throwAbortReason` +- Rename `createRemixStub` to `createRoutesStub` ([#11692](https://github.com/remix-run/react-router/pull/11692)) +- Remove `@remix-run/router` deprecated `detectErrorBoundary` option in favor of `mapRouteProperties` ([#11751](https://github.com/remix-run/react-router/pull/11751)) +- Add `react-router/dom` subpath export to properly enable `react-dom` as an optional `peerDependency` ([#11851](https://github.com/remix-run/react-router/pull/11851)) + - This ensures that we don't blindly `import ReactDOM from "react-dom"` in `` in order to access `ReactDOM.flushSync()`, since that would break `createMemoryRouter` use cases in non-DOM environments + - DOM environments should import from `react-router/dom` to get the proper component that makes `ReactDOM.flushSync()` available: + - If you are using the Vite plugin, use this in your `entry.client.tsx`: + - `import { HydratedRouter } from 'react-router/dom'` + - If you are not using the Vite plugin and are manually calling `createBrowserRouter`/`createHashRouter`: + - `import { RouterProvider } from "react-router/dom"` +- Remove `future.v7_fetcherPersist` flag ([#11731](https://github.com/remix-run/react-router/pull/11731)) +- Allow returning `undefined` from loaders and actions ([#11680](https://github.com/remix-run/react-router/pull/11680), [#12057]([https://github.com/remix-run/react-router/pull/1205)) +- Use `createRemixRouter`/`RouterProvider` in `entry.client` instead of `RemixBrowser` ([#11469](https://github.com/remix-run/react-router/pull/11469)) +- Remove the deprecated `json` utility ([#12146](https://github.com/remix-run/react-router/pull/12146)) + - You can use [`Response.json`](https://developer.mozilla.org/en-US/docs/Web/API/Response/json_static) if you still need to construct JSON responses in your app + +### Major Changes (`@react-router/*`) + +- Remove `future.v3_singleFetch` flag ([#11522](https://github.com/remix-run/react-router/pull/11522)) +- Drop support for Node 16 and 18, update minimum Node version to 20 ([#11690](https://github.com/remix-run/react-router/pull/11690), [#12171](https://github.com/remix-run/react-router/pull/12171)) + - Remove `installGlobals()` as this should no longer be necessary +- Add `exports` field to all packages ([#11675](https://github.com/remix-run/react-router/pull/11675)) +- No longer re-export APIs from `react-router` through different runtime/adapter packages ([#11702](https://github.com/remix-run/react-router/pull/11702)) +- 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` + - `createSessionStorage` + - 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` + - `createMemorySessionStorageFactory` +- Consolidate types previously duplicated across `@remix-run/router`, `@remix-run/server-runtime`, and `@remix-run/react` now that they all live in `react-router` ([#12177](https://github.com/remix-run/react-router/pull/12177)) + - Examples: `LoaderFunction`, `LoaderFunctionArgs`, `ActionFunction`, `ActionFunctionArgs`, `DataFunctionArgs`, `RouteManifest`, `LinksFunction`, `Route`, `EntryRoute` + - The `RouteManifest` type used by the "remix" code is now slightly stricter because it is using the former `@remix-run/router` `RouteManifest` + - `Record -> Record` + - Removed `AppData` type in favor of inlining `unknown` in the few locations it was used + - Removed `ServerRuntimeMeta*` types in favor of the `Meta*` types they were duplicated from +- Migrate Remix v2 type generics to React Router ([#12180](https://github.com/remix-run/react-router/pull/12180)) + - These generics are provided for Remix v2 migration purposes + - These generics and the APIs they exist on should be considered informally deprecated in favor of the new `Route.*` types + - Anyone migrating from React Router v6 should probably not leverage these new generics and should migrate straight to the `Route.*` types + - For React Router v6 users, these generics are new and should not impact your app, with one exception + - `useFetcher` previously had an optional generic (used primarily by Remix v2) that expected the data type + - This has been updated in v7 to expect the type of the function that generates the data (i.e., `typeof loader`/`typeof action`) + - Therefore, you should update your usages: + - ❌ `useFetcher()` + - ✅ `useFetcher()` +- Update `cookie` dependency to `^1.0.1` - please see the [release notes](https://github.com/jshttp/cookie/releases) for any breaking changes ([#12172](https://github.com/remix-run/react-router/pull/12172)) +- `@react-router/cloudflare` - 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)) +- `@react-router/cloudflare` - The `@remix-run/cloudflare-workers` package has been deprecated. Remix consumers migrating to React Router should use the `@react-router/cloudflare` package directly. For guidance on how to use `@react-router/cloudflare` within a Cloudflare Workers context, refer to the Cloudflare Workers template. ([#11801](https://github.com/remix-run/react-router/pull/11801)) +- `@react-router/dev` - For Remix consumers migrating to React Router, the `vitePlugin` and `cloudflareDevProxyVitePlugin` exports have been renamed and moved. ([#11904](https://github.com/remix-run/react-router/pull/11904)) +- `@react-router/dev` - For Remix consumers migrating to React Router who used the Vite plugin's `buildEnd` hook, the resolved `reactRouterConfig` object no longer contains a `publicPath` property since this belongs to Vite, not React Router ([#11575](https://github.com/remix-run/react-router/pull/11575)) +- `@react-router/dev` - For Remix consumers migrating to React Router, the Vite plugin's `manifest` option has been removed ([#11573](https://github.com/remix-run/react-router/pull/11573)) +- `@react-router/dev` - Update default `isbot` version to v5 and drop support for `isbot@3` ([#11770](https://github.com/remix-run/react-router/pull/11770)) + - If you have `isbot@4` or `isbot@5` in your `package.json`: + - You do not need to make any changes + - If you have `isbot@3` in your `package.json` and you have your own `entry.server.tsx` file in your repo + - You do not need to make any changes + - You can upgrade to `isbot@5` independent of the React Router v7 upgrade + - If you have `isbot@3` in your `package.json` and you do not have your own `entry.server.tsx` file in your repo + - You are using the internal default entry provided by React Router v7 and you will need to upgrade to `isbot@5` in your `package.json` +- `@react-router/dev` - For Remix consumers migrating to React Router, Vite manifests (i.e. `.vite/manifest.json`) are now written within each build subdirectory, e.g. `build/client/.vite/manifest.json` and `build/server/.vite/manifest.json` instead of `build/.vite/client-manifest.json` and `build/.vite/server-manifest.json`. This means that the build output is now much closer to what you'd expect from a typical Vite project. ([#11573](https://github.com/remix-run/react-router/pull/11573)) + - Originally the Remix Vite plugin moved all Vite manifests to a root-level `build/.vite` directory to avoid accidentally serving them in production, particularly from the client build. This was later improved with additional logic that deleted these Vite manifest files at the end of the build process unless Vite's `build.manifest` had been enabled within the app's Vite config. This greatly reduced the risk of accidentally serving the Vite manifests in production since they're only present when explicitly asked for. As a result, we can now assume that consumers will know that they need to manage these additional files themselves, and React Router can safely generate a more standard Vite build output. + +### Minor Changes + +- `react-router` - Params, loader data, and action data as props for route component exports ([#11961](https://github.com/remix-run/react-router/pull/11961)) +- `react-router` - Add route module type generation ([#12019](https://github.com/remix-run/react-router/pull/12019)) +- `react-router` - Remove duplicate `RouterProvider` implementations ([#11679](https://github.com/remix-run/react-router/pull/11679)) +- `react-router` - Stabilize `unstable_dataStrategy` ([#11969](https://github.com/remix-run/react-router/pull/11969)) +- `react-router` - Stabilize `unstable_patchRoutesOnNavigation` ([#11970](https://github.com/remix-run/react-router/pull/11970)) +- `react-router` - Add prefetching support to `Link`/`NavLink` when using Remix SSR ([#11402](https://github.com/remix-run/react-router/pull/11402)) +- `react-router` - Enhance `ScrollRestoration` so it can restore properly on an SSR'd document load ([#11401](https://github.com/remix-run/react-router/pull/11401)) +- `@react-router/dev` - Add support for the `prerender` config in the React Router vite plugin, to support existing SSG use-cases ([#11539](https://github.com/remix-run/react-router/pull/11539)) +- `@react-router/dev` - Remove internal `entry.server.spa.tsx` implementation which was not compatible with the Single Fetch async hydration approach ([#11681](https://github.com/remix-run/react-router/pull/11681)) +- `@react-router/serve`: Update `express.static` configurations to support new `prerender` API ([#11547](https://github.com/remix-run/react-router/pull/11547)) + - Assets in the `build/client/assets` folder are served as before, with a 1-year immutable `Cache-Control` header + - Static files outside of assets, such as pre-rendered `.html` and `.data` files are not served with a specific `Cache-Control` header + - `.data` files are served with `Content-Type: text/x-turbo` + - For some reason, when adding this via `express.static`, it seems to also add a `Cache-Control: public, max-age=0` to `.data` files + +### Patch Changes + +- Replace `substr` with `substring` ([#12080](https://github.com/remix-run/react-router/pull/12080)) +- `react-router` - Fix redirects returned from loaders/actions using `data()` ([#12021](https://github.com/remix-run/react-router/pull/12021)) +- `@react-router/dev` - Enable prerendering for resource routes ([#12200](https://github.com/remix-run/react-router/pull/12200)) +- `@react-router/dev` - resolve config directory relative to flat output file structure ([#12187](https://github.com/remix-run/react-router/pull/12187)) + +### Changes by Package + +- [`react-router`](https://github.com/remix-run/react-router/blob/react-router%407.0.0/packages/react-router/CHANGELOG.md#700) +- [`@react-router/architect`](https://github.com/remix-run/react-router/blob/react-router%407.0.0/packages/react-router-architect/CHANGELOG.md#700) +- [`@react-router/cloudflare`](https://github.com/remix-run/react-router/blob/react-router%407.0.0/packages/react-router-cloudflare/CHANGELOG.md#700) +- [`@react-router/dev`](https://github.com/remix-run/react-router/blob/react-router%407.0.0/packages/react-router-dev/CHANGELOG.md#700) +- [`@react-router/express`](https://github.com/remix-run/react-router/blob/react-router%407.0.0/packages/react-router-express/CHANGELOG.md#700) +- [`@react-router/fs-routes`](https://github.com/remix-run/react-router/blob/react-router%407.0.0/packages/react-router-fs-routes/CHANGELOG.md#700) +- [`@react-router/node`](https://github.com/remix-run/react-router/blob/react-router%407.0.0/packages/react-router-node/CHANGELOG.md#700) +- [`@react-router/remix-config-routes-adapter`](https://github.com/remix-run/react-router/blob/react-router%407.0.0/packages/react-router-remix-config-routes-adapter/CHANGELOG.md#700) +- [`@react-router/serve`](https://github.com/remix-run/react-router/blob/react-router%407.0.0/packages/react-router-serve/CHANGELOG.md#700) + +# **Full Changelog**: [`v6.28.0...v7.0.0`](https://github.com/remix-run/react-router/compare/react-router@6.28.0...react-router@7.0.0) + ## v6.28.0 Date: 2024-11-06 @@ -236,6 +812,8 @@ Date: 2024-11-06 **Full Changelog**: [`v6.27.0...v6.28.0`](https://github.com/remix-run/react-router/compare/react-router@6.27.0...react-router@6.28.0) +> > > > > > > dev + ## v6.27.0 Date: 2024-10-11 diff --git a/contributors.yml b/contributors.yml index 6669c0344f..91550cb756 100644 --- a/contributors.yml +++ b/contributors.yml @@ -42,6 +42,7 @@ - bhbs - bilalk711 - bobziroll +- Brendonovich - BrianT1414 - brockross - brookslybrand @@ -281,6 +282,7 @@ - vijaypushkin - vikingviolinist - vishwast03 +- vitekzach - vonagam - WalkAlone0325 - willemarcel diff --git a/packages/create-react-router/CHANGELOG.md b/packages/create-react-router/CHANGELOG.md new file mode 100644 index 0000000000..41300a3cda --- /dev/null +++ b/packages/create-react-router/CHANGELOG.md @@ -0,0 +1,5 @@ +# `create-react-router` + +## 7.0.0 + +Initial release. diff --git a/packages/create-react-router/package.json b/packages/create-react-router/package.json index 8cb7c2aae5..24515680be 100644 --- a/packages/create-react-router/package.json +++ b/packages/create-react-router/package.json @@ -1,6 +1,6 @@ { "name": "create-react-router", - "version": "6.26.2", + "version": "7.0.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 new file mode 100644 index 0000000000..3ebb931978 --- /dev/null +++ b/packages/react-router-architect/CHANGELOG.md @@ -0,0 +1,27 @@ +# `@react-router/architect` + +## 7.0.0 + +### 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` + - `createSessionStorage` + + 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` + - `createMemorySessionStorageFactory` + +### Patch Changes + +- Updated dependencies: + - `react-router@7.0.0` + - `@react-router/node@7.0.0` diff --git a/packages/react-router-architect/package.json b/packages/react-router-architect/package.json index db9234affc..74650fafef 100644 --- a/packages/react-router-architect/package.json +++ b/packages/react-router-architect/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/architect", - "version": "6.26.2", + "version": "7.0.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 new file mode 100644 index 0000000000..780ea18d0d --- /dev/null +++ b/packages/react-router-cloudflare/CHANGELOG.md @@ -0,0 +1,31 @@ +# `@react-router/cloudflare` + +## 7.0.0 + +### Major Changes + +- 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` + - `createSessionStorage` + + 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` + - `createMemorySessionStorageFactory` + +### Minor Changes + +- The `@remix-run/cloudflare-workers` package has been deprecated. Remix consumers migrating to React Router should use the `@react-router/cloudflare` package directly. For guidance on how to use `@react-router/cloudflare` within a Cloudflare Workers context, refer to the Cloudflare Workers template. ([#11801](https://github.com/remix-run/react-router/pull/11801)) + +### Patch Changes + +- Updated dependencies: + - `react-router@7.0.0` diff --git a/packages/react-router-cloudflare/package.json b/packages/react-router-cloudflare/package.json index aa6925b134..43b442a51e 100644 --- a/packages/react-router-cloudflare/package.json +++ b/packages/react-router-cloudflare/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/cloudflare", - "version": "6.26.2", + "version": "7.0.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 527d7f844e..bda0e22275 100644 --- a/packages/react-router-dev/CHANGELOG.md +++ b/packages/react-router-dev/CHANGELOG.md @@ -1,4 +1,142 @@ -# `@remix-run/dev` +# `@react-router/dev` + +## 7.0.0 + +### Major Changes + +- For Remix consumers migrating to React Router, the `vitePlugin` and `cloudflareDevProxyVitePlugin` exports have been renamed and moved. ([#11904](https://github.com/remix-run/react-router/pull/11904)) + + ```diff + -import { + - vitePlugin as remix, + - cloudflareDevProxyVitePlugin, + -} from "@remix/dev"; + + +import { reactRouter } from "@react-router/dev/vite"; + +import { cloudflareDevProxy } from "@react-router/dev/vite/cloudflare"; + ``` + +- Remove single_fetch future flag. ([#11522](https://github.com/remix-run/react-router/pull/11522)) + +- update minimum node version to 18 ([#11690](https://github.com/remix-run/react-router/pull/11690)) + +- Add `exports` field to all packages ([#11675](https://github.com/remix-run/react-router/pull/11675)) + +- node package no longer re-exports from react-router ([#11702](https://github.com/remix-run/react-router/pull/11702)) + +- For Remix consumers migrating to React Router who used the Vite plugin's `buildEnd` hook, the resolved `reactRouterConfig` object no longer contains a `publicPath` property since this belongs to Vite, not React Router. ([#11575](https://github.com/remix-run/react-router/pull/11575)) + +- For Remix consumers migrating to React Router, the Vite plugin's `manifest` option has been removed. ([#11573](https://github.com/remix-run/react-router/pull/11573)) + + The `manifest` option been superseded by the more powerful `buildEnd` hook since it's passed the `buildManifest` argument. You can still write the build manifest to disk if needed, but you'll most likely find it more convenient to write any logic depending on the build manifest within the `buildEnd` hook itself. + + If you were using the `manifest` option, you can replace it with a `buildEnd` hook that writes the manifest to disk like this: + + ```ts + // react-router.config.ts + import type { Config } from "@react-router/dev/config"; + import { writeFile } from "node:fs/promises"; + + export default { + async buildEnd({ buildManifest }) { + await writeFile( + "build/manifest.json", + JSON.stringify(buildManifest, null, 2), + "utf-8" + ); + }, + } satisfies Config; + ``` + +- Consolidate types previously duplicated across `@remix-run/router`, `@remix-run/server-runtime`, and `@remix-run/react` now that they all live in `react-router` ([#12177](https://github.com/remix-run/react-router/pull/12177)) + + - Examples: `LoaderFunction`, `LoaderFunctionArgs`, `ActionFunction`, `ActionFunctionArgs`, `DataFunctionArgs`, `RouteManifest`, `LinksFunction`, `Route`, `EntryRoute` + - The `RouteManifest` type used by the "remix" code is now slightly stricter because it is using the former `@remix-run/router` `RouteManifest` + - `Record -> Record` + - Removed `AppData` type in favor of inlining `unknown` in the few locations it was used + - Removed `ServerRuntimeMeta*` types in favor of the `Meta*` types they were duplicated from + +- Update default `isbot` version to v5 and drop support for `isbot@3` ([#11770](https://github.com/remix-run/react-router/pull/11770)) + + - If you have `isbot@4` or `isbot@5` in your `package.json`: + - You do not need to make any changes + - If you have `isbot@3` in your `package.json` and you have your own `entry.server.tsx` file in your repo + - You do not need to make any changes + - You can upgrade to `isbot@5` independent of the React Router v7 upgrade + - If you have `isbot@3` in your `package.json` and you do not have your own `entry.server.tsx` file in your repo + - You are using the internal default entry provided by React Router v7 and you will need to upgrade to `isbot@5` in your `package.json` + +- Drop support for Node 18, update minimum Node vestion to 20 ([#12171](https://github.com/remix-run/react-router/pull/12171)) + + - Remove `installGlobals()` as this should no longer be necessary + +- For Remix consumers migrating to React Router, Vite manifests (i.e. `.vite/manifest.json`) are now written within each build subdirectory, e.g. `build/client/.vite/manifest.json` and `build/server/.vite/manifest.json` instead of `build/.vite/client-manifest.json` and `build/.vite/server-manifest.json`. This means that the build output is now much closer to what you'd expect from a typical Vite project. ([#11573](https://github.com/remix-run/react-router/pull/11573)) + + Originally the Remix Vite plugin moved all Vite manifests to a root-level `build/.vite` directory to avoid accidentally serving them in production, particularly from the client build. This was later improved with additional logic that deleted these Vite manifest files at the end of the build process unless Vite's `build.manifest` had been enabled within the app's Vite config. This greatly reduced the risk of accidentally serving the Vite manifests in production since they're only present when explicitly asked for. As a result, we can now assume that consumers will know that they need to manage these additional files themselves, and React Router can safely generate a more standard Vite build output. + +### Minor Changes + +- Params, loader data, and action data as props for route component exports ([#11961](https://github.com/remix-run/react-router/pull/11961)) + + ```tsx + export default function Component({ params, loaderData, actionData }) {} + + export function HydrateFallback({ params }) {} + export function ErrorBoundary({ params, loaderData, actionData }) {} + ``` + +- Remove internal entry.server.spa.tsx implementation ([#11681](https://github.com/remix-run/react-router/pull/11681)) + +- Add `prefix` route config helper to `@react-router/dev/routes` ([#12094](https://github.com/remix-run/react-router/pull/12094)) + +- ### Typesafety improvements ([#12019](https://github.com/remix-run/react-router/pull/12019)) + + React Router now generates types for each of your route modules. + You can access those types by importing them from `./+types.`. + For example: + + ```ts + // app/routes/product.tsx + import type * as Route from "./+types.product"; + + export function loader({ params }: Route.LoaderArgs) {} + + export default function Component({ loaderData }: Route.ComponentProps) {} + ``` + + 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 + + In the future, we plan to add types for the rest of the route module exports: `meta`, `links`, `headers`, `shouldRevalidate`, etc. + We also plan to generate types for typesafe `Link`s: + + ```tsx + + // ^^^^^^^^^^^^^ ^^^^^^^^^ + // typesafe `to` and `params` based on the available routes in your app + ``` + + 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) + +### Patch Changes + +- Enable prerendering for resource routes ([#12200](https://github.com/remix-run/react-router/pull/12200)) +- chore: warn instead of error for min node version in CLI ([#12270](https://github.com/remix-run/react-router/pull/12270)) +- chore: re-enable development warnings through a `development` exports condition. ([#12269](https://github.com/remix-run/react-router/pull/12269)) +- include root "react-dom" module for optimization ([#12060](https://github.com/remix-run/react-router/pull/12060)) +- resolve config directory relative to flat output file structure ([#12187](https://github.com/remix-run/react-router/pull/12187)) +- if we are in SAP mode, always render the `index.html` for hydration ([#12268](https://github.com/remix-run/react-router/pull/12268)) +- fix(react-router): (v7) fix static prerender of non-ascii characters ([#12161](https://github.com/remix-run/react-router/pull/12161)) +- Updated dependencies: + - `react-router@7.0.0` + - `@react-router/serve@7.0.0` + - `@react-router/node@7.0.0` ## 2.9.0 diff --git a/packages/react-router-dev/package.json b/packages/react-router-dev/package.json index dff8981c86..6e96c41877 100644 --- a/packages/react-router-dev/package.json +++ b/packages/react-router-dev/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/dev", - "version": "6.26.2", + "version": "7.0.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 new file mode 100644 index 0000000000..ec70fc3bf9 --- /dev/null +++ b/packages/react-router-dom/CHANGELOG.md @@ -0,0 +1,56 @@ +# react-router-dom + +## 7.0.0 + +### Major Changes + +- Remove the original `defer` implementation in favor of using raw promises via single fetch and `turbo-stream`. This removes these exports from React Router: ([#11744](https://github.com/remix-run/react-router/pull/11744)) + + - `defer` + - `AbortedDeferredError` + - `type TypedDeferredData` + - `UNSAFE_DeferredData` + - `UNSAFE_DEFERRED_SYMBOL`, + +- Use `createRemixRouter`/`RouterProvider` in `entry.client` instead of `RemixBrowser` ([#11469](https://github.com/remix-run/react-router/pull/11469)) + +- Remove single\_fetch future flag. ([#11522](https://github.com/remix-run/react-router/pull/11522)) + +- Remove `future.v7_startTransition` flag ([#11696](https://github.com/remix-run/react-router/pull/11696)) + +- Remove `future.v7_normalizeFormMethod` future flag ([#11697](https://github.com/remix-run/react-router/pull/11697)) + +- Allow returning `undefined` from actions and loaders ([#11680](https://github.com/remix-run/react-router/pull/11680)) + +- update minimum node version to 18 ([#11690](https://github.com/remix-run/react-router/pull/11690)) + +- Remove `future.v7_prependBasename` from the ionternalized `@remix-run/router` package ([#11726](https://github.com/remix-run/react-router/pull/11726)) + +- Remove `future.v7_throwAbortReason` from internalized `@remix-run/router` package ([#11728](https://github.com/remix-run/react-router/pull/11728)) + +- Add `exports` field to all packages ([#11675](https://github.com/remix-run/react-router/pull/11675)) + +- node package no longer re-exports from react-router ([#11702](https://github.com/remix-run/react-router/pull/11702)) + +- updates the minimum React version to 18 ([#11689](https://github.com/remix-run/react-router/pull/11689)) + +- - Remove the `future.v7_partialHydration` flag ([#11725](https://github.com/remix-run/react-router/pull/11725)) + - This also removes the `` prop + - To migrate, move the `fallbackElement` to a `hydrateFallbackElement`/`HydrateFallback` on your root route + - Also worth nothing there is a related breaking changer with this future flag: + - Without `future.v7_partialHydration` (when using `fallbackElement`), `state.navigation` was populated during the initial load + - With `future.v7_partialHydration`, `state.navigation` remains in an `"idle"` state during the initial load + +- Remove `future.v7_fetcherPersist` flag ([#11731](https://github.com/remix-run/react-router/pull/11731)) + +### Minor Changes + +- Add prefetching support to `Link`/`NavLink` when using Remix SSR ([#11402](https://github.com/remix-run/react-router/pull/11402)) +- Enhance `ScrollRestoration` so it can restore properly on an SSR'd document load ([#11401](https://github.com/remix-run/react-router/pull/11401)) +- Add built-in Remix-style hydration support to `RouterProvider`. When running from a Remix-SSR'd HTML payload with the proper `window` variables (`__remixContext`, `__remixManifest`, `__remixRouteModules`), you don't need to pass a `router` prop and `RouterProvider` will create the `router` for you internally. ([#11396](https://github.com/remix-run/react-router/pull/11396)) ([#11400](https://github.com/remix-run/react-router/pull/11400)) + +### Patch Changes + +- Memoize some `RouterProvider` internals to reduce uneccesary re-renders ([#11817](https://github.com/remix-run/react-router/pull/11817)) +- Updated dependencies: + - `react-router@7.0.0` diff --git a/packages/react-router-dom/package.json b/packages/react-router-dom/package.json index d1739391bf..612cd7e7c9 100644 --- a/packages/react-router-dom/package.json +++ b/packages/react-router-dom/package.json @@ -1,6 +1,6 @@ { "name": "react-router-dom", - "version": "6.26.2", + "version": "7.0.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 241eec2502..de8e8cdda8 100644 --- a/packages/react-router-express/CHANGELOG.md +++ b/packages/react-router-express/CHANGELOG.md @@ -1,4 +1,22 @@ -# `@remix-run/express` +# `@react-router/express` + +## 7.0.0 + +### Major Changes + +- Remove single_fetch future flag. ([#11522](https://github.com/remix-run/react-router/pull/11522)) +- update minimum node version to 18 ([#11690](https://github.com/remix-run/react-router/pull/11690)) +- Add `exports` field to all packages ([#11675](https://github.com/remix-run/react-router/pull/11675)) +- node package no longer re-exports from react-router ([#11702](https://github.com/remix-run/react-router/pull/11702)) +- Drop support for Node 18, update minimum Node vestion to 20 ([#12171](https://github.com/remix-run/react-router/pull/12171)) + + - Remove `installGlobals()` as this should no longer be necessary + +### Patch Changes + +- Updated dependencies: + - `react-router@7.0.0` + - `@react-router/node@7.0.0` ## 2.9.0 diff --git a/packages/react-router-express/package.json b/packages/react-router-express/package.json index 839a5c3603..dbf9d52485 100644 --- a/packages/react-router-express/package.json +++ b/packages/react-router-express/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/express", - "version": "6.26.2", + "version": "7.0.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 new file mode 100644 index 0000000000..33442d22b9 --- /dev/null +++ b/packages/react-router-fs-routes/CHANGELOG.md @@ -0,0 +1,10 @@ +# `@react-router/fs-routes` + +## 7.0.0 + +Initial release. + +### Patch Changes + +- Updated dependencies: + - `@react-router/dev@7.0.0` diff --git a/packages/react-router-fs-routes/package.json b/packages/react-router-fs-routes/package.json index 9f741feba8..e584775d6f 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": "6.26.2", + "version": "7.0.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 7bad0a5271..632d3553fe 100644 --- a/packages/react-router-node/CHANGELOG.md +++ b/packages/react-router-node/CHANGELOG.md @@ -1,4 +1,44 @@ -# `@remix-run/node` +# `@react-router/node` + +## 7.0.0 + +### Major Changes + +- 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` + - `createSessionStorage` + + 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` + - `createMemorySessionStorageFactory` + +- update minimum node version to 18 ([#11690](https://github.com/remix-run/react-router/pull/11690)) + +- Add `exports` field to all packages ([#11675](https://github.com/remix-run/react-router/pull/11675)) + +- node package no longer re-exports from react-router ([#11702](https://github.com/remix-run/react-router/pull/11702)) + +- Drop support for Node 18, update minimum Node vestion to 20 ([#12171](https://github.com/remix-run/react-router/pull/12171)) + + - Remove `installGlobals()` as this should no longer be necessary + +### Patch Changes + +- Add createRequestListener to @react-router/node ([#12319](https://github.com/remix-run/react-router/pull/12319)) +- Remove unstable upload handler. ([#12015](https://github.com/remix-run/react-router/pull/12015)) +- Remove unneeded dependency on @web3-storage/multipart-parser ([#12274](https://github.com/remix-run/react-router/pull/12274)) +- Updated dependencies: + - `react-router@7.0.0` ## 2.9.0 diff --git a/packages/react-router-node/package.json b/packages/react-router-node/package.json index 38f1ba31ea..64172b2f4d 100644 --- a/packages/react-router-node/package.json +++ b/packages/react-router-node/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/node", - "version": "6.26.2", + "version": "7.0.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 new file mode 100644 index 0000000000..c67fc1a1dd --- /dev/null +++ b/packages/react-router-remix-routes-option-adapter/CHANGELOG.md @@ -0,0 +1,5 @@ +# `@react-router/remix-config-routes-adapter` + +## 7.0.0 + +Initial release. diff --git a/packages/react-router-remix-routes-option-adapter/package.json b/packages/react-router-remix-routes-option-adapter/package.json index 016408d107..9387c37975 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": "6.26.2", + "version": "7.0.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 1b739354d1..a1f425a755 100644 --- a/packages/react-router-serve/CHANGELOG.md +++ b/packages/react-router-serve/CHANGELOG.md @@ -1,4 +1,27 @@ -# `@remix-run/serve` +# `@react-router/serve` + +## 7.0.0 + +### Major Changes + +- Remove single_fetch future flag. ([#11522](https://github.com/remix-run/react-router/pull/11522)) +- update minimum node version to 18 ([#11690](https://github.com/remix-run/react-router/pull/11690)) +- Add `exports` field to all packages ([#11675](https://github.com/remix-run/react-router/pull/11675)) +- node package no longer re-exports from react-router ([#11702](https://github.com/remix-run/react-router/pull/11702)) + +### Patch Changes + +- Update `express.static` configurations to support prerendering ([#11547](https://github.com/remix-run/react-router/pull/11547)) + + - Assets in the `build/client/assets` folder are served as before, with a 1-year immutable `Cache-Control` header + - Static files outside of assets, such as pre-rendered `.html` and `.data` files are not served with a specific `Cache-Control` header + - `.data` files are served with `Content-Type: text/x-turbo` + - For some reason, when adding this via `express.static`, it seems to also add a `Cache-Control: public, max-age=0` to `.data` files + +- Updated dependencies: + - `react-router@7.0.0` + - `@react-router/express@7.0.0` + - `@react-router/node@7.0.0` ## 2.9.0 diff --git a/packages/react-router-serve/package.json b/packages/react-router-serve/package.json index 3eceff70e0..4152187db6 100644 --- a/packages/react-router-serve/package.json +++ b/packages/react-router-serve/package.json @@ -1,6 +1,6 @@ { "name": "@react-router/serve", - "version": "6.26.2", + "version": "7.0.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 b39d7c7b73..9360f675af 100644 --- a/packages/react-router/CHANGELOG.md +++ b/packages/react-router/CHANGELOG.md @@ -1,5 +1,253 @@ # `react-router` +## 7.0.0 + +### Major Changes + +- Remove the original `defer` implementation in favor of using raw promises via single fetch and `turbo-stream`. This removes these exports from React Router: ([#11744](https://github.com/remix-run/react-router/pull/11744)) + + - `defer` + - `AbortedDeferredError` + - `type TypedDeferredData` + - `UNSAFE_DeferredData` + - `UNSAFE_DEFERRED_SYMBOL`, + +- - Collapse `@remix-run/router` into `react-router` ([#11505](https://github.com/remix-run/react-router/pull/11505)) + - Collapse `react-router-dom` into `react-router` + - Collapse `@remix-run/server-runtime` into `react-router` + - Collapse `@remix-run/testing` into `react-router` + +- Remove single_fetch future flag. ([#11522](https://github.com/remix-run/react-router/pull/11522)) + +- Drop support for Node 16, React Router SSR now requires Node 18 or higher ([#11391](https://github.com/remix-run/react-router/pull/11391)) + +- Remove `future.v7_startTransition` flag ([#11696](https://github.com/remix-run/react-router/pull/11696)) + +- - Expose the underlying router promises from the following APIs for compsition in React 19 APIs: ([#11521](https://github.com/remix-run/react-router/pull/11521)) + - `useNavigate()` + - `useSubmit` + - `useFetcher().load` + - `useFetcher().submit` + - `useRevalidator.revalidate` + +- 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` + - `createSessionStorage` + + 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` + - `createMemorySessionStorageFactory` + +- Imports/Exports cleanup ([#11840](https://github.com/remix-run/react-router/pull/11840)) + + - Removed the following exports that were previously public API from `@remix-run/router` + - types + - `AgnosticDataIndexRouteObject` + - `AgnosticDataNonIndexRouteObject` + - `AgnosticDataRouteMatch` + - `AgnosticDataRouteObject` + - `AgnosticIndexRouteObject` + - `AgnosticNonIndexRouteObject` + - `AgnosticRouteMatch` + - `AgnosticRouteObject` + - `TrackedPromise` + - `unstable_AgnosticPatchRoutesOnMissFunction` + - `Action` -> exported as `NavigationType` via `react-router` + - `Router` exported as `DataRouter` to differentiate from RR's `` + - API + - `getToPathname` (`@private`) + - `joinPaths` (`@private`) + - `normalizePathname` (`@private`) + - `resolveTo` (`@private`) + - `stripBasename` (`@private`) + - `createBrowserHistory` -> in favor of `createBrowserRouter` + - `createHashHistory` -> in favor of `createHashRouter` + - `createMemoryHistory` -> in favor of `createMemoryRouter` + - `createRouter` + - `createStaticHandler` -> in favor of wrapper `createStaticHandler` in RR Dom + - `getStaticContextFromError` + - Removed the following exports that were previously public API from `react-router` + - `Hash` + - `Pathname` + - `Search` + +- update minimum node version to 18 ([#11690](https://github.com/remix-run/react-router/pull/11690)) + +- Remove `future.v7_prependBasename` from the ionternalized `@remix-run/router` package ([#11726](https://github.com/remix-run/react-router/pull/11726)) + +- Migrate Remix type generics to React Router ([#12180](https://github.com/remix-run/react-router/pull/12180)) + + - These generics are provided for Remix v2 migration purposes + - These generics and the APIs they exist on should be considered informally deprecated in favor of the new `Route.*` types + - Anyone migrating from React Router v6 should probably not leverage these new generics and should migrate straight to the `Route.*` types + - For React Router v6 users, these generics are new and should not impact your app, with one exception + - `useFetcher` previously had an optional generic (used primarily by Remix v2) that expected the data type + - This has been updated in v7 to expect the type of the function that generates the data (i.e., `typeof loader`/`typeof action`) + - Therefore, you should update your usages: + - ❌ `useFetcher()` + - ✅ `useFetcher()` + +- Remove `future.v7_throwAbortReason` from internalized `@remix-run/router` package ([#11728](https://github.com/remix-run/react-router/pull/11728)) + +- Add `exports` field to all packages ([#11675](https://github.com/remix-run/react-router/pull/11675)) + +- node package no longer re-exports from react-router ([#11702](https://github.com/remix-run/react-router/pull/11702)) + +- renamed RemixContext to FrameworkContext ([#11705](https://github.com/remix-run/react-router/pull/11705)) + +- updates the minimum React version to 18 ([#11689](https://github.com/remix-run/react-router/pull/11689)) + +- PrefetchPageDescriptor replaced by PageLinkDescriptor ([#11960](https://github.com/remix-run/react-router/pull/11960)) + +- - Consolidate types previously duplicated across `@remix-run/router`, `@remix-run/server-runtime`, and `@remix-run/react` now that they all live in `react-router` ([#12177](https://github.com/remix-run/react-router/pull/12177)) + - Examples: `LoaderFunction`, `LoaderFunctionArgs`, `ActionFunction`, `ActionFunctionArgs`, `DataFunctionArgs`, `RouteManifest`, `LinksFunction`, `Route`, `EntryRoute` + - The `RouteManifest` type used by the "remix" code is now slightly stricter because it is using the former `@remix-run/router` `RouteManifest` + - `Record -> Record` + - Removed `AppData` type in favor of inlining `unknown` in the few locations it was used + - Removed `ServerRuntimeMeta*` types in favor of the `Meta*` types they were duplicated from + +- - Remove the `future.v7_partialHydration` flag ([#11725](https://github.com/remix-run/react-router/pull/11725)) + - This also removes the `` prop + - To migrate, move the `fallbackElement` to a `hydrateFallbackElement`/`HydrateFallback` on your root route + - Also worth nothing there is a related breaking changer with this future flag: + - Without `future.v7_partialHydration` (when using `fallbackElement`), `state.navigation` was populated during the initial load + - With `future.v7_partialHydration`, `state.navigation` remains in an `"idle"` state during the initial load + +- Remove `v7_relativeSplatPath` future flag ([#11695](https://github.com/remix-run/react-router/pull/11695)) + +- Drop support for Node 18, update minimum Node vestion to 20 ([#12171](https://github.com/remix-run/react-router/pull/12171)) + + - Remove `installGlobals()` as this should no longer be necessary + +- Remove remaining future flags ([#11820](https://github.com/remix-run/react-router/pull/11820)) + + - React Router `v7_skipActionErrorRevalidation` + - Remix `v3_fetcherPersist`, `v3_relativeSplatPath`, `v3_throwAbortReason` + +- rename createRemixStub to createRoutesStub ([#11692](https://github.com/remix-run/react-router/pull/11692)) + +- Remove `@remix-run/router` deprecated `detectErrorBoundary` option in favor of `mapRouteProperties` ([#11751](https://github.com/remix-run/react-router/pull/11751)) + +- Add `react-router/dom` subpath export to properly enable `react-dom` as an optional `peerDependency` ([#11851](https://github.com/remix-run/react-router/pull/11851)) + + - This ensures that we don't blindly `import ReactDOM from "react-dom"` in `` in order to access `ReactDOM.flushSync()`, since that would break `createMemoryRouter` use cases in non-DOM environments + - DOM environments should import from `react-router/dom` to get the proper component that makes `ReactDOM.flushSync()` available: + - If you are using the Vite plugin, use this in your `entry.client.tsx`: + - `import { HydratedRouter } from 'react-router/dom'` + - If you are not using the Vite plugin and are manually calling `createBrowserRouter`/`createHashRouter`: + - `import { RouterProvider } from "react-router/dom"` + +- Remove `future.v7_fetcherPersist` flag ([#11731](https://github.com/remix-run/react-router/pull/11731)) + +- Update `cookie` dependency to `^1.0.1` - please see the [release notes](https://github.com/jshttp/cookie/releases) for any breaking changes ([#12172](https://github.com/remix-run/react-router/pull/12172)) + +### Minor Changes + +- - Add support for `prerender` config in the React Router vite plugin, to support existing SSG use-cases ([#11539](https://github.com/remix-run/react-router/pull/11539)) + - You can use the `prerender` config to pre-render your `.html` and `.data` files at build time and then serve them statically at runtime (either from a running server or a CDN) + - `prerender` can either be an array of string paths, or a function (sync or async) that returns an array of strings so that you can dynamically generate the paths by talking to your CMS, etc. + + ```ts + // react-router.config.ts + import type { Config } from "@react-router/dev/config"; + + export default { + async prerender() { + let slugs = await fakeGetSlugsFromCms(); + // Prerender these paths into `.html` files at build time, and `.data` + // files if they have loaders + return ["/", "/about", ...slugs.map((slug) => `/product/${slug}`)]; + }, + } satisfies Config; + + async function fakeGetSlugsFromCms() { + await new Promise((r) => setTimeout(r, 1000)); + return ["shirt", "hat"]; + } + ``` + +- Params, loader data, and action data as props for route component exports ([#11961](https://github.com/remix-run/react-router/pull/11961)) + + ```tsx + export default function Component({ params, loaderData, actionData }) {} + + export function HydrateFallback({ params }) {} + export function ErrorBoundary({ params, loaderData, actionData }) {} + ``` + +- Remove duplicate `RouterProvider` impliementations ([#11679](https://github.com/remix-run/react-router/pull/11679)) + +- ### Typesafety improvements ([#12019](https://github.com/remix-run/react-router/pull/12019)) + + React Router now generates types for each of your route modules. + You can access those types by importing them from `./+types.`. + For example: + + ```ts + // app/routes/product.tsx + import type * as Route from "./+types.product"; + + export function loader({ params }: Route.LoaderArgs) {} + + export default function Component({ loaderData }: Route.ComponentProps) {} + ``` + + 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 + + In the future, we plan to add types for the rest of the route module exports: `meta`, `links`, `headers`, `shouldRevalidate`, etc. + We also plan to generate types for typesafe `Link`s: + + ```tsx + + // ^^^^^^^^^^^^^ ^^^^^^^^^ + // typesafe `to` and `params` based on the available routes in your app + ``` + + 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) + +- Stabilize `unstable_dataStrategy` ([#11969](https://github.com/remix-run/react-router/pull/11969)) + +- Stabilize `unstable_patchRoutesOnNavigation` ([#11970](https://github.com/remix-run/react-router/pull/11970)) + +### Patch Changes + +- No changes ([`506329c4e`](https://github.com/remix-run/react-router/commit/506329c4e2e7aba9837cbfa44df6103b49423745)) + +- chore: re-enable development warnings through a `development` exports condition. ([#12269](https://github.com/remix-run/react-router/pull/12269)) + +- Remove unstable upload handler. ([#12015](https://github.com/remix-run/react-router/pull/12015)) + +- Remove unneeded dependency on @web3-storage/multipart-parser ([#12274](https://github.com/remix-run/react-router/pull/12274)) + +- Fix redirects returned from loaders/actions using `data()` ([#12021](https://github.com/remix-run/react-router/pull/12021)) + +- fix(react-router): (v7) fix static prerender of non-ascii characters ([#12161](https://github.com/remix-run/react-router/pull/12161)) + +- Replace `substr` with `substring` ([#12080](https://github.com/remix-run/react-router/pull/12080)) + +- Remove the deprecated `json` utility ([#12146](https://github.com/remix-run/react-router/pull/12146)) + + - You can use [`Response.json`](https://developer.mozilla.org/en-US/docs/Web/API/Response/json_static) if you still need to construct JSON responses in your app + +- Remove unneeded dependency on source-map ([#12275](https://github.com/remix-run/react-router/pull/12275)) + ## 6.28.0 ### Minor Changes diff --git a/packages/react-router/__tests__/dom/data-browser-router-test.tsx b/packages/react-router/__tests__/dom/data-browser-router-test.tsx index 255d2b04b0..f7ab074550 100644 --- a/packages/react-router/__tests__/dom/data-browser-router-test.tsx +++ b/packages/react-router/__tests__/dom/data-browser-router-test.tsx @@ -1,4 +1,3 @@ -import type { ErrorResponse, Fetcher, RouterState } from "react-router"; import "@testing-library/jest-dom"; import { act, @@ -9,7 +8,12 @@ import { } from "@testing-library/react"; import { JSDOM } from "jsdom"; import * as React from "react"; -import type { RouteObject } from "../../index"; +import type { + RouteObject, + ErrorResponse, + Fetcher, + RouterState, +} from "../../index"; import { Await, UNSAFE_DataRouterStateContext as DataRouterStateContext, diff --git a/packages/react-router/__tests__/dom/partial-hydration-test.tsx b/packages/react-router/__tests__/dom/partial-hydration-test.tsx index 7f6c9e259d..edb2f6b389 100644 --- a/packages/react-router/__tests__/dom/partial-hydration-test.tsx +++ b/packages/react-router/__tests__/dom/partial-hydration-test.tsx @@ -1,8 +1,7 @@ import "@testing-library/jest-dom"; import { act, render, screen, waitFor } from "@testing-library/react"; import * as React from "react"; -import type { LoaderFunction } from "react-router"; -import {} from "react-router"; +import type { LoaderFunction } from "../../index"; import { Outlet, RouterProvider as ReactRouter_RouterProvider, @@ -94,31 +93,31 @@ describe("Partial Hydration Behavior", () => { parentDfd.resolve("PARENT DATA"); expect(getHtml(container)).toMatchInlineSnapshot(` - "
-

- Root -

-

- Parent Loading... -

-
" - `); + "
+

+ Root +

+

+ Parent Loading... +

+
" + `); childDfd.resolve("CHILD DATA"); await waitFor(() => screen.getByText(/CHILD DATA/)); expect(getHtml(container)).toMatchInlineSnapshot(` - "
-

- Root -

-

- Parent - PARENT DATA -

-

- Child - CHILD DATA -

-
" - `); + "
+

+ Root +

+

+ Parent - PARENT DATA +

+

+ Child - CHILD DATA +

+
" + `); }); it("supports partial hydration w/patchRoutesOnNavigation (root fallback)", async () => { @@ -183,28 +182,28 @@ describe("Partial Hydration Behavior", () => { parentDfd.resolve("PARENT DATA"); expect(getHtml(container)).toMatchInlineSnapshot(` - "
-

- Root Loading... -

-
" - `); + "
+

+ Root Loading... +

+
" + `); childDfd.resolve("CHILD DATA"); await waitFor(() => screen.getByText(/CHILD DATA/)); expect(getHtml(container)).toMatchInlineSnapshot(` - "
-

- Root -

-

- Parent - PARENT DATA -

-

- Child - CHILD DATA -

-
" - `); + "
+

+ Root +

+

+ Parent - PARENT DATA +

+

+ Child - CHILD DATA +

+
" + `); }); }); }); diff --git a/packages/react-router/package.json b/packages/react-router/package.json index 958095b1a2..7d78b492c5 100644 --- a/packages/react-router/package.json +++ b/packages/react-router/package.json @@ -1,6 +1,6 @@ { "name": "react-router", - "version": "6.26.2", + "version": "7.0.0", "description": "Declarative routing for React", "keywords": [ "react",