Skip to content

Update dependency react-router-dom to v7#378

Open
mend-for-github-com[bot] wants to merge 1 commit into
mainfrom
whitesource-remediate/react-router-dom-7.x
Open

Update dependency react-router-dom to v7#378
mend-for-github-com[bot] wants to merge 1 commit into
mainfrom
whitesource-remediate/react-router-dom-7.x

Conversation

@mend-for-github-com

@mend-for-github-com mend-for-github-com Bot commented Jun 22, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

Package Type Update Change
react-router-dom (source) dependencies major 6.30.37.0.0

By merging this PR, the issue #388 will be automatically resolved and closed:

Severity CVSS Score Vulnerability
High High 7.5 CVE-2026-40181

Release Notes

remix-run/react-router (react-router-dom)

v7.0.0

Compare Source

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:

// 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 the fetch API
  • react@18, react-dom@18
Adopted Future Flag Behaviors

Remix and React Router follow an API Development Strategy leveraging "Future Flags" to avoid introducing a slew of breaking changes in a major release. Instead, breaking changes are introduced in 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
    • future.v7_relativeSplatPath
    • future.v7_startTransition
    • future.v7_fetcherPersist
    • future.v7_normalizeFormMethod
    • future.v7_partialHydration
    • future.v7_skipActionStatusRevalidation
  • Remix v2 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 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)

-import {
-  vitePlugin as remix,
-  cloudflareDevProxyVitePlugin,
-} from "@​remix/dev";

+import { reactRouter } from "@​react-router/dev/vite";
+import { cloudflareDevProxy } from "@​react-router/dev/vite/cloudflare";

Removed 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)

If you were using the manifest option, you can replace it with a buildEnd hook that writes the manifest to disk like this:

// 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;
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.

// 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:

// 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.

// 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 in Remix v2, you can combine @react-router/remix-config-routes-adapter with @remix-run/v1-route-convention to adapt this to React Router:

// 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.

// 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"),
+  ]),
+];
Type-safety improvements

React Router now generates types for each of your route modules and passes typed props to route module component exports (#​11961, #​12019). You can access those types by importing them from ./+types/<route filename without extension>.

See How To > Route Module Type Safety and Explanations > Type Safety for more details.

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)

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)
    • This removes these exports from React Router:
      • defer
      • AbortedDeferredError
      • type TypedDeferredData
      • UNSAFE_DeferredData
      • UNSAFE_DEFERRED_SYMBOL
  • Collapse packages into react-router(#​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, #​11690)
  • Remove future.v7_startTransition flag (#​11696)
  • Expose the underlying router promises from the following APIs for composition in React 19 APIs: (#​11521)
  • Remove future.v7_normalizeFormMethod future flag (#​11697)
  • Imports/Exports cleanup (#​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 <Router>
      • 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)
  • Remove future.v7_throwAbortReason from internalized @remix-run/router package (#​11728)
  • Add exports field to all packages (#​11675)
  • Renamed RemixContext to FrameworkContext (#​11705)
  • Update the minimum React version to 18 (#​11689)
  • PrefetchPageDescriptor replaced by PageLinkDescriptor (#​11960)
  • Remove the future.v7_partialHydration flag (#​11725)
    • This also removes the <RouterProvider fallbackElement> 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)
  • Remove remaining future flags (#​11820)
    • React Router v7_skipActionErrorRevalidation
    • Remix v3_fetcherPersist, v3_relativeSplatPath, v3_throwAbortReason
  • Rename createRemixStub to createRoutesStub (#​11692)
  • Remove @remix-run/router deprecated detectErrorBoundary option in favor of mapRouteProperties (#​11751)
  • Add react-router/dom subpath export to properly enable react-dom as an optional peerDependency (#​11851)
    • This ensures that we don't blindly import ReactDOM from "react-dom" in <RouterProvider> 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)
  • Allow returning undefined from loaders and actions (#​11680, #​12057)
  • Use createRemixRouter/RouterProvider in entry.client instead of RemixBrowser (#​11469)
  • Remove the deprecated json utility (#​12146)
    • You can use Response.json if you still need to construct JSON responses in your app
Major Changes (@react-router/*)
  • Remove future.v3_singleFetch flag (#​11522)
  • Drop support for Node 16 and 18, update minimum Node version to 20 (#​11690, #​12171)
    • Remove installGlobals() as this should no longer be necessary
  • Add exports field to all packages (#​11675)
  • No longer re-export APIs from react-router through different runtime/adapter packages (#​11702)
  • For Remix consumers migrating to React Router, the crypto global from the 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)
      • 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
    • 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)
    • 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<string, Route> -> Record<string, Route | undefined>
    • 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)
    • 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<LoaderData>()
        • useFetcher<typeof loader>()
  • Update cookie dependency to ^1.0.1 - please see the release notes for any breaking changes (#​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)
  • @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)
  • @react-router/dev - For Remix consumers migrating to React Router, the vitePlugin and cloudflareDevProxyVitePlugin exports have been renamed and moved. (#​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)
  • @react-router/dev - For Remix consumers migrating to React Router, the Vite plugin's manifest option has been removed (#​11573)
  • @react-router/dev - Update default isbot version to v5 and drop support for isbot@3 (#​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)
    • 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)
  • react-router - Add route module type generation (#​12019)
  • react-router - Remove duplicate RouterProvider implementations (#​11679)
  • react-router - Stabilize unstable_dataStrategy (#​11969)
  • react-router - Stabilize unstable_patchRoutesOnNavigation (#​11970)
  • react-router - Add prefetching support to Link/NavLink when using Remix SSR (#​11402)
  • react-router - Enhance ScrollRestoration so it can restore properly on an SSR'd document load (#​11401)
  • @react-router/dev - Add support for the prerender config in the React Router vite plugin, to support existing SSG use-cases (#​11539)
  • @react-router/dev - Remove internal entry.server.spa.tsx implementation which was not compatible with the Single Fetch async hydration approach (#​11681)
  • @react-router/serve: Update express.static configurations to support new prerender API (#​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)
  • react-router - Fix redirects returned from loaders/actions using data() (#​12021)
  • @react-router/dev - Enable prerendering for resource routes (#​12200)
  • @react-router/dev - resolve config directory relative to flat output file structure (#​12187)
Changes by Package

Full Changelog: v6.28.0...v7.0.0

v6.30.4

Compare Source


  • If you want to rebase/retry this PR, check this box

@mend-for-github-com mend-for-github-com Bot added the security fix Security fix generated by Mend label Jun 22, 2026
@mend-for-github-com mend-for-github-com Bot changed the title Update dependency react-router-dom to v7 Update dependency react-router-dom to v7 - autoclosed Jun 24, 2026
@mend-for-github-com mend-for-github-com Bot deleted the whitesource-remediate/react-router-dom-7.x branch June 24, 2026 10:43
@mend-for-github-com mend-for-github-com Bot changed the title Update dependency react-router-dom to v7 - autoclosed Update dependency react-router-dom to v7 Jun 24, 2026
@mend-for-github-com mend-for-github-com Bot reopened this Jun 24, 2026
@mend-for-github-com mend-for-github-com Bot force-pushed the whitesource-remediate/react-router-dom-7.x branch from a60f38b to df08f43 Compare June 24, 2026 11:03
@mend-for-github-com mend-for-github-com Bot force-pushed the whitesource-remediate/react-router-dom-7.x branch from df08f43 to de9ef31 Compare June 25, 2026 08:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

security fix Security fix generated by Mend

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants