diff --git a/package-lock.json b/package-lock.json
index d7a9601967..17c1a53fe7 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -3575,15 +3575,6 @@
"vite": "^3.0.0 || ^4.0.0 || ^5.0.0"
}
},
- "node_modules/@remix-run/router": {
- "version": "1.21.0",
- "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.21.0.tgz",
- "integrity": "sha512-xfSkCAchbdG5PnbrKqFWwia4Bi61nH+wm8wLEqfHDyp7Y3dZzgqS2itV8i4gAq9pC2HsTpwyBC6Ds8VHZ96JlA==",
- "peer": true,
- "engines": {
- "node": ">=14.0.0"
- }
- },
"node_modules/@rollup/plugin-node-resolve": {
"version": "15.3.0",
"resolved": "https://registry.npmjs.org/@rollup/plugin-node-resolve/-/plugin-node-resolve-15.3.0.tgz",
@@ -16588,6 +16579,7 @@
"version": "18.3.1",
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-18.3.1.tgz",
"integrity": "sha512-5m4nQKp+rZRb09LNH59GM4BxTh9251/ylbKIbpe7TpGxfJ+9kv6BLkLBXIjjspbgbnIBNqlI23tRnTWT0snUIw==",
+ "license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
@@ -16613,35 +16605,42 @@
}
},
"node_modules/react-router": {
- "version": "6.28.0",
- "resolved": "https://registry.npmjs.org/react-router/-/react-router-6.28.0.tgz",
- "integrity": "sha512-HrYdIFqdrnhDw0PqG/AKjAqEqM7AvxCz0DQ4h2W8k6nqmc5uRBYDag0SBxx9iYz5G8gnuNVLzUe13wl9eAsXXg==",
- "peer": true,
+ "version": "7.0.2",
+ "resolved": "https://registry.npmjs.org/react-router/-/react-router-7.0.2.tgz",
+ "integrity": "sha512-m5AcPfTRUcjwmhBzOJGEl6Y7+Crqyju0+TgTQxoS4SO+BkWbhOrcfZNq6wSWdl2BBbJbsAoBUb8ZacOFT+/JlA==",
+ "license": "MIT",
"dependencies": {
- "@remix-run/router": "1.21.0"
+ "@types/cookie": "^0.6.0",
+ "cookie": "^1.0.1",
+ "set-cookie-parser": "^2.6.0",
+ "turbo-stream": "2.4.0"
},
"engines": {
- "node": ">=14.0.0"
+ "node": ">=20.0.0"
},
"peerDependencies": {
- "react": ">=16.8"
+ "react": ">=18",
+ "react-dom": ">=18"
+ },
+ "peerDependenciesMeta": {
+ "react-dom": {
+ "optional": true
+ }
}
},
- "node_modules/react-router-dom": {
- "version": "6.28.0",
- "resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.28.0.tgz",
- "integrity": "sha512-kQ7Unsl5YdyOltsPGl31zOjLrDv+m2VcIEcIHqYYD3Lp0UppLjrzcfJqDJwXxFw3TH/yvapbnUvPlAj7Kx5nbg==",
- "peer": true,
- "dependencies": {
- "@remix-run/router": "1.21.0",
- "react-router": "6.28.0"
- },
+ "node_modules/react-router/node_modules/@types/cookie": {
+ "version": "0.6.0",
+ "resolved": "https://registry.npmjs.org/@types/cookie/-/cookie-0.6.0.tgz",
+ "integrity": "sha512-4Kh9a6B2bQciAhf7FSuMRRkUWecJgJu9nPnx3yzpsfXX/c50REIqpHY4C82bXP90qrLtXtkDxTZosYO3UpOwlA==",
+ "license": "MIT"
+ },
+ "node_modules/react-router/node_modules/cookie": {
+ "version": "1.0.2",
+ "resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
+ "integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
+ "license": "MIT",
"engines": {
- "node": ">=14.0.0"
- },
- "peerDependencies": {
- "react": ">=16.8",
- "react-dom": ">=16.8"
+ "node": ">=18"
}
},
"node_modules/readable-stream": {
@@ -17148,6 +17147,7 @@
"version": "0.23.2",
"resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.23.2.tgz",
"integrity": "sha512-UOShsPwz7NrMUqhR6t0hWjFduvOzbtv7toDH1/hIrfRNIDBnnBWd0CwJTGvTpngVlmwGCdP9/Zl/tVrDqcuYzQ==",
+ "license": "MIT",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0"
@@ -17176,6 +17176,12 @@
"randombytes": "^2.1.0"
}
},
+ "node_modules/set-cookie-parser": {
+ "version": "2.7.1",
+ "resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
+ "integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
+ "license": "MIT"
+ },
"node_modules/set-function-length": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz",
@@ -18349,6 +18355,12 @@
"fsevents": "~2.3.3"
}
},
+ "node_modules/turbo-stream": {
+ "version": "2.4.0",
+ "resolved": "https://registry.npmjs.org/turbo-stream/-/turbo-stream-2.4.0.tgz",
+ "integrity": "sha512-FHncC10WpBd2eOmGwpmQsWLDoK4cqsA/UT/GqNoaKOQnT8uzhtCbg3EoUDMvqpOSAI0S26mr0rkjzbOO6S3v1g==",
+ "license": "ISC"
+ },
"node_modules/type-check": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz",
@@ -19377,7 +19389,7 @@
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "react-router-dom": "^6.28.0"
+ "react-router": "^7"
}
},
"packages/ts/frontend": {
@@ -20105,6 +20117,7 @@
"@types/validator": "^13.11.2",
"@web/test-runner": "^0.19.0",
"chai-dom": "^1.11.0",
+ "react-router": "^7.0.2",
"sinon": "^16.0.0",
"sinon-chai": "^3.7.0",
"typescript": "5.6.2"
@@ -20112,7 +20125,7 @@
"peerDependencies": {
"react": "^18",
"react-dom": "^18",
- "react-router-dom": "^6.28.0"
+ "react-router": "^7"
}
},
"packages/ts/react-crud": {
diff --git a/packages/java/gradle-plugin/src/functionalTest/kotlin/com/vaadin/hilla/gradle/plugin/AbstractGradleTest.kt b/packages/java/gradle-plugin/src/functionalTest/kotlin/com/vaadin/hilla/gradle/plugin/AbstractGradleTest.kt
index 29bde04ab5..3ca12b13ec 100644
--- a/packages/java/gradle-plugin/src/functionalTest/kotlin/com/vaadin/hilla/gradle/plugin/AbstractGradleTest.kt
+++ b/packages/java/gradle-plugin/src/functionalTest/kotlin/com/vaadin/hilla/gradle/plugin/AbstractGradleTest.kt
@@ -26,7 +26,7 @@ import org.junit.Before
abstract class AbstractGradleTest {
val hillaVersion = System.getenv("hilla.version").takeUnless { it.isNullOrEmpty() } ?: "24.7-SNAPSHOT"
- val flowVersion = System.getenv("flow.version").takeUnless { it.isNullOrEmpty() } ?: "24.6-SNAPSHOT"
+ val flowVersion = System.getenv("flow.version").takeUnless { it.isNullOrEmpty() } ?: "24.7-SNAPSHOT"
/**
* The testing Gradle project. Automatically deleted after every test.
* Don't use TemporaryFolder JUnit `@Rule` since it will always delete the folder afterward,
diff --git a/packages/java/tests/gradle/single-module-tests/frontend/App.tsx b/packages/java/tests/gradle/single-module-tests/frontend/App.tsx
index 6b7546d1ed..b84dcf6ea7 100644
--- a/packages/java/tests/gradle/single-module-tests/frontend/App.tsx
+++ b/packages/java/tests/gradle/single-module-tests/frontend/App.tsx
@@ -1,5 +1,5 @@
import router from 'Frontend/routes.js';
-import { RouterProvider } from 'react-router-dom';
+import { RouterProvider } from 'react-router';
export default function App() {
return ;
diff --git a/packages/java/tests/gradle/single-module-tests/frontend/_views/MainLayout.tsx b/packages/java/tests/gradle/single-module-tests/frontend/_views/MainLayout.tsx
index 9c7629fcf6..3b5fa36c6a 100644
--- a/packages/java/tests/gradle/single-module-tests/frontend/_views/MainLayout.tsx
+++ b/packages/java/tests/gradle/single-module-tests/frontend/_views/MainLayout.tsx
@@ -5,7 +5,7 @@ import { Scroller } from '@vaadin/react-components/Scroller.js';
import Placeholder from 'Frontend/components/placeholder/Placeholder.js';
import { MenuProps, routes, useViewMatches, ViewRouteObject } from 'Frontend/routes.js';
import { Suspense } from 'react';
-import { NavLink, Outlet } from 'react-router-dom';
+import { NavLink, Outlet } from 'react-router';
import css from './MainLayout.module.css';
type MenuRoute = ViewRouteObject &
diff --git a/packages/java/tests/gradle/single-module-tests/frontend/routes.tsx b/packages/java/tests/gradle/single-module-tests/frontend/routes.tsx
index 502d533321..7714b5e819 100644
--- a/packages/java/tests/gradle/single-module-tests/frontend/routes.tsx
+++ b/packages/java/tests/gradle/single-module-tests/frontend/routes.tsx
@@ -1,7 +1,7 @@
import HelloReactView from './_views/helloreact/HelloReactView.js';
import MainLayout from './_views/MainLayout.js';
import { lazy } from 'react';
-import { createBrowserRouter, IndexRouteObject, NonIndexRouteObject, useMatches } from 'react-router-dom';
+import { createBrowserRouter, IndexRouteObject, NonIndexRouteObject, useMatches } from 'react-router';
const AboutView = lazy(async () => import('./_views/about/AboutView.js'));
export type MenuProps = Readonly<{
diff --git a/packages/java/tests/gradle/single-module/gradle.properties b/packages/java/tests/gradle/single-module/gradle.properties
index f3e5f486ea..71177fc1a9 100644
--- a/packages/java/tests/gradle/single-module/gradle.properties
+++ b/packages/java/tests/gradle/single-module/gradle.properties
@@ -1,4 +1,4 @@
org.gradle.daemon=false
hillaVersion=24.7-SNAPSHOT
-flowVersion=24.6-SNAPSHOT
+flowVersion=24.7-SNAPSHOT
vaadinComponentsVersion=24.6-SNAPSHOT
diff --git a/packages/java/tests/gradle/single-module/src/main/frontend/App.tsx b/packages/java/tests/gradle/single-module/src/main/frontend/App.tsx
index 3aaf8e8ec7..265f231fb5 100644
--- a/packages/java/tests/gradle/single-module/src/main/frontend/App.tsx
+++ b/packages/java/tests/gradle/single-module/src/main/frontend/App.tsx
@@ -1,5 +1,5 @@
import router from './routes';
-import { RouterProvider } from 'react-router-dom';
+import { RouterProvider } from 'react-router';
export default function App() {
return ;
diff --git a/packages/java/tests/gradle/single-module/src/main/frontend/_views/MainLayout.tsx b/packages/java/tests/gradle/single-module/src/main/frontend/_views/MainLayout.tsx
index 89e9a07721..70bf9e967f 100644
--- a/packages/java/tests/gradle/single-module/src/main/frontend/_views/MainLayout.tsx
+++ b/packages/java/tests/gradle/single-module/src/main/frontend/_views/MainLayout.tsx
@@ -5,7 +5,7 @@ import { Scroller } from '@vaadin/react-components/Scroller.js';
import Placeholder from '../components/placeholder/Placeholder';
import { MenuProps, routes, useViewMatches, ViewRouteObject } from '../routes';
import { Suspense } from 'react';
-import { NavLink, Outlet } from 'react-router-dom';
+import { NavLink, Outlet } from 'react-router';
import css from './MainLayout.module.css';
type MenuRoute = ViewRouteObject &
diff --git a/packages/java/tests/gradle/single-module/src/main/frontend/routes.tsx b/packages/java/tests/gradle/single-module/src/main/frontend/routes.tsx
index ded3e68db1..387b3f25e0 100644
--- a/packages/java/tests/gradle/single-module/src/main/frontend/routes.tsx
+++ b/packages/java/tests/gradle/single-module/src/main/frontend/routes.tsx
@@ -1,7 +1,7 @@
import HelloReactView from './_views/helloreact/HelloReactView';
import MainLayout from './_views/MainLayout';
import { lazy } from 'react';
-import { createBrowserRouter, IndexRouteObject, NonIndexRouteObject, useMatches } from 'react-router-dom';
+import { createBrowserRouter, IndexRouteObject, NonIndexRouteObject, useMatches } from 'react-router';
const AboutView = lazy(async () => import('./_views/about/AboutView'));
export type MenuProps = Readonly<{
diff --git a/packages/java/tests/spring/native/frontend/App.tsx b/packages/java/tests/spring/native/frontend/App.tsx
index 5d068e2165..2614586c54 100644
--- a/packages/java/tests/spring/native/frontend/App.tsx
+++ b/packages/java/tests/spring/native/frontend/App.tsx
@@ -1,6 +1,6 @@
import router from 'Frontend/routes.js';
import { AuthContext, useAuth } from 'Frontend/useAuth.js';
-import { RouterProvider } from 'react-router-dom';
+import { RouterProvider } from 'react-router';
export default function App() {
const auth = useAuth();
diff --git a/packages/java/tests/spring/native/frontend/routes.tsx b/packages/java/tests/spring/native/frontend/routes.tsx
index e39a5ebf85..783d9fd051 100644
--- a/packages/java/tests/spring/native/frontend/routes.tsx
+++ b/packages/java/tests/spring/native/frontend/routes.tsx
@@ -1,4 +1,4 @@
-import {createBrowserRouter, RouteObject} from 'react-router-dom';
+import {createBrowserRouter, RouteObject} from 'react-router';
import {ChatView} from "Frontend/views/ChatView.js";
import {LoginView} from "Frontend/views/LoginView.js";
import {ReadOnlyGrid} from "Frontend/views/ReadOnlyGrid";
diff --git a/packages/java/tests/spring/native/frontend/util/routing.ts b/packages/java/tests/spring/native/frontend/util/routing.ts
index ff80af3541..93f26fbbb2 100644
--- a/packages/java/tests/spring/native/frontend/util/routing.ts
+++ b/packages/java/tests/spring/native/frontend/util/routing.ts
@@ -1,4 +1,4 @@
-import { useMatches } from 'react-router-dom';
+import { useMatches } from 'react-router';
type RouteMetadata = {
[key: string]: any;
diff --git a/packages/java/tests/spring/native/frontend/views/AuthControl.tsx b/packages/java/tests/spring/native/frontend/views/AuthControl.tsx
index dac26aa713..d5b2c3f2fd 100644
--- a/packages/java/tests/spring/native/frontend/views/AuthControl.tsx
+++ b/packages/java/tests/spring/native/frontend/views/AuthControl.tsx
@@ -1,6 +1,6 @@
import { AccessProps, AuthContext } from 'Frontend/useAuth.js';
import { ReactNode, useContext } from 'react';
-import { Navigate, useMatches } from 'react-router-dom';
+import { Navigate, useMatches } from 'react-router';
export type AuthControlProps = Readonly<{
fallback?: ReactNode;
diff --git a/packages/java/tests/spring/native/frontend/views/MainLayout.tsx b/packages/java/tests/spring/native/frontend/views/MainLayout.tsx
index cc173c49be..e9e4404d83 100644
--- a/packages/java/tests/spring/native/frontend/views/MainLayout.tsx
+++ b/packages/java/tests/spring/native/frontend/views/MainLayout.tsx
@@ -7,7 +7,7 @@ import Placeholder from 'Frontend/components/placeholder/Placeholder';
import { AuthContext } from 'Frontend/useAuth.js';
import { useRouteMetadata } from 'Frontend/util/routing';
import { Suspense, useContext } from 'react';
-import { NavLink, Outlet } from 'react-router-dom';
+import { NavLink, Outlet } from 'react-router';
const navLinkClasses = ({ isActive }: any) => {
return `block rounded-m p-s ${isActive ? 'bg-primary-10 text-primary' : 'text-body'}`;
diff --git a/packages/java/tests/spring/react-grid-test/frontend/App.tsx b/packages/java/tests/spring/react-grid-test/frontend/App.tsx
index 6b7546d1ed..b84dcf6ea7 100644
--- a/packages/java/tests/spring/react-grid-test/frontend/App.tsx
+++ b/packages/java/tests/spring/react-grid-test/frontend/App.tsx
@@ -1,5 +1,5 @@
import router from 'Frontend/routes.js';
-import { RouterProvider } from 'react-router-dom';
+import { RouterProvider } from 'react-router';
export default function App() {
return ;
diff --git a/packages/java/tests/spring/react-grid-test/frontend/MainLayout.tsx b/packages/java/tests/spring/react-grid-test/frontend/MainLayout.tsx
index 779dbd23bb..91a331da81 100644
--- a/packages/java/tests/spring/react-grid-test/frontend/MainLayout.tsx
+++ b/packages/java/tests/spring/react-grid-test/frontend/MainLayout.tsx
@@ -2,7 +2,7 @@ import { AppLayout } from '@vaadin/react-components/AppLayout.js';
import { DrawerToggle } from '@vaadin/react-components/DrawerToggle.js';
import { Scroller } from '@vaadin/react-components/Scroller.js';
import { routes } from 'Frontend/routes.js';
-import { NavLink, Outlet } from 'react-router-dom';
+import { NavLink, Outlet } from 'react-router';
export default function MainLayout() {
const menuRoutes = routes[0]!.children;
diff --git a/packages/java/tests/spring/react-grid-test/frontend/routes.tsx b/packages/java/tests/spring/react-grid-test/frontend/routes.tsx
index 669155f6b8..d22e2791e0 100644
--- a/packages/java/tests/spring/react-grid-test/frontend/routes.tsx
+++ b/packages/java/tests/spring/react-grid-test/frontend/routes.tsx
@@ -1,4 +1,4 @@
-import { createBrowserRouter } from 'react-router-dom';
+import { createBrowserRouter } from 'react-router';
import MainLayout from './MainLayout.js';
import { AutoCrudView } from 'Frontend/views/AutoCrudView.js';
import { AutoFormView } from 'Frontend/views/AutoFormView.js';
diff --git a/packages/java/tests/spring/react-i18n/frontend/App.tsx b/packages/java/tests/spring/react-i18n/frontend/App.tsx
index 6b7546d1ed..b84dcf6ea7 100644
--- a/packages/java/tests/spring/react-i18n/frontend/App.tsx
+++ b/packages/java/tests/spring/react-i18n/frontend/App.tsx
@@ -1,5 +1,5 @@
import router from 'Frontend/routes.js';
-import { RouterProvider } from 'react-router-dom';
+import { RouterProvider } from 'react-router';
export default function App() {
return ;
diff --git a/packages/java/tests/spring/react-i18n/frontend/MainLayout.tsx b/packages/java/tests/spring/react-i18n/frontend/MainLayout.tsx
index 779dbd23bb..91a331da81 100644
--- a/packages/java/tests/spring/react-i18n/frontend/MainLayout.tsx
+++ b/packages/java/tests/spring/react-i18n/frontend/MainLayout.tsx
@@ -2,7 +2,7 @@ import { AppLayout } from '@vaadin/react-components/AppLayout.js';
import { DrawerToggle } from '@vaadin/react-components/DrawerToggle.js';
import { Scroller } from '@vaadin/react-components/Scroller.js';
import { routes } from 'Frontend/routes.js';
-import { NavLink, Outlet } from 'react-router-dom';
+import { NavLink, Outlet } from 'react-router';
export default function MainLayout() {
const menuRoutes = routes[0]!.children;
diff --git a/packages/java/tests/spring/react-i18n/frontend/routes.tsx b/packages/java/tests/spring/react-i18n/frontend/routes.tsx
index 6e3ff2e25c..79d9fc95d7 100644
--- a/packages/java/tests/spring/react-i18n/frontend/routes.tsx
+++ b/packages/java/tests/spring/react-i18n/frontend/routes.tsx
@@ -1,4 +1,4 @@
-import { createBrowserRouter } from 'react-router-dom';
+import { createBrowserRouter } from 'react-router';
import MainLayout from './MainLayout.js';
import BasicI18NView from './_views/BasicI18NView';
export const routes = [
diff --git a/packages/java/tests/spring/react-signals/frontend/index.tsx b/packages/java/tests/spring/react-signals/frontend/index.tsx
index cd303c7cf9..8c2c5f76b8 100644
--- a/packages/java/tests/spring/react-signals/frontend/index.tsx
+++ b/packages/java/tests/spring/react-signals/frontend/index.tsx
@@ -12,7 +12,7 @@
import { createElement } from 'react';
import { createRoot } from 'react-dom/client';
-import { RouterProvider } from 'react-router-dom';
+import { RouterProvider } from 'react-router';
import { router } from 'Frontend/generated/routes.js';
import { AuthProvider } from 'Frontend/util/auth';
diff --git a/packages/java/tests/spring/react-signals/frontend/views/SharedSignalSecurity.tsx b/packages/java/tests/spring/react-signals/frontend/views/SharedSignalSecurity.tsx
index 588325b153..5d34d53819 100644
--- a/packages/java/tests/spring/react-signals/frontend/views/SharedSignalSecurity.tsx
+++ b/packages/java/tests/spring/react-signals/frontend/views/SharedSignalSecurity.tsx
@@ -2,7 +2,7 @@ import { Button } from '@vaadin/react-components';
import { useSignal } from '@vaadin/hilla-react-signals';
import { SecureNumberSignalService } from 'Frontend/generated/endpoints.js';
import { useAuth } from 'Frontend/util/auth.js';
-import { useNavigate } from 'react-router-dom';
+import { useNavigate } from 'react-router';
const userCounter = SecureNumberSignalService.userCounter();
const adminCounter = SecureNumberSignalService.adminCounter();
diff --git a/packages/ts/file-router/package.json b/packages/ts/file-router/package.json
index dd19d91d40..4c3d8951d1 100644
--- a/packages/ts/file-router/package.json
+++ b/packages/ts/file-router/package.json
@@ -59,7 +59,7 @@
"peerDependencies": {
"react": "^18.2.0",
"react-dom": "^18.2.0",
- "react-router-dom": "^6.28.0"
+ "react-router": "^7"
},
"devDependencies": {
"@esm-bundle/chai": "^4.3.4-fix.0",
diff --git a/packages/ts/file-router/src/runtime/RouterConfigurationBuilder.ts b/packages/ts/file-router/src/runtime/RouterConfigurationBuilder.ts
index 0180c653b7..5156c61dcb 100644
--- a/packages/ts/file-router/src/runtime/RouterConfigurationBuilder.ts
+++ b/packages/ts/file-router/src/runtime/RouterConfigurationBuilder.ts
@@ -1,12 +1,7 @@
/* eslint-disable @typescript-eslint/consistent-type-assertions */
import { protectRoute } from '@vaadin/hilla-react-auth';
import { type ComponentType, createElement } from 'react';
-import {
- createBrowserRouter,
- type IndexRouteObject,
- type NonIndexRouteObject,
- type RouteObject,
-} from 'react-router-dom';
+import { createBrowserRouter, type IndexRouteObject, type NonIndexRouteObject, type RouteObject } from 'react-router';
import { convertComponentNameToTitle } from '../shared/convertComponentNameToTitle.js';
import { transformTree } from '../shared/transformTree.js';
import type {
@@ -358,22 +353,7 @@ export class RouterConfigurationBuilder {
return {
routes,
- router: createBrowserRouter([...routes], {
- basename: new URL(document.baseURI).pathname,
- future: {
- // eslint-disable-next-line camelcase
- v7_fetcherPersist: true,
- // eslint-disable-next-line camelcase
- v7_normalizeFormMethod: true,
- // eslint-disable-next-line camelcase
- v7_partialHydration: true,
- // eslint-disable-next-line camelcase
- v7_relativeSplatPath: true,
- // eslint-disable-next-line camelcase
- v7_skipActionErrorRevalidation: true,
- },
- ...options,
- }),
+ router: createBrowserRouter([...routes], { basename: new URL(document.baseURI).pathname, ...options }),
};
}
diff --git a/packages/ts/file-router/src/runtime/useViewConfig.ts b/packages/ts/file-router/src/runtime/useViewConfig.ts
index 5f94bc0bb7..5e9e2acac5 100644
--- a/packages/ts/file-router/src/runtime/useViewConfig.ts
+++ b/packages/ts/file-router/src/runtime/useViewConfig.ts
@@ -1,5 +1,5 @@
-import type { UIMatch } from '@remix-run/router';
-import { useMatches } from 'react-router-dom';
+import type { UIMatch } from 'react-router';
+import { useMatches } from 'react-router';
import type { ViewConfig } from '../types.js';
/**
diff --git a/packages/ts/file-router/src/types.d.ts b/packages/ts/file-router/src/types.d.ts
index 1840180676..6ed24949f8 100644
--- a/packages/ts/file-router/src/types.d.ts
+++ b/packages/ts/file-router/src/types.d.ts
@@ -1,4 +1,4 @@
-import type { createBrowserRouter, RouteObject } from 'react-router-dom';
+import type { createBrowserRouter, RouteObject } from 'react-router';
export type ViewConfig = Readonly<{
/**
diff --git a/packages/ts/file-router/test/mocks/react-router-dom.ts b/packages/ts/file-router/test/mocks/react-router-dom.ts
deleted file mode 100644
index 0ffd68daef..0000000000
--- a/packages/ts/file-router/test/mocks/react-router-dom.ts
+++ /dev/null
@@ -1,5 +0,0 @@
-import sinon from 'sinon';
-
-export const browserRouter = { 'browser-router': true };
-
-export const createBrowserRouter = sinon.stub().returns(browserRouter);
diff --git a/packages/ts/file-router/test/runtime/RouterConfigurationBuilder.spec.tsx b/packages/ts/file-router/test/runtime/RouterConfigurationBuilder.spec.tsx
index 08898a8645..206304317f 100644
--- a/packages/ts/file-router/test/runtime/RouterConfigurationBuilder.spec.tsx
+++ b/packages/ts/file-router/test/runtime/RouterConfigurationBuilder.spec.tsx
@@ -4,7 +4,6 @@ import { createElement } from 'react';
import sinonChai from 'sinon-chai';
import { RouterConfigurationBuilder } from '../../src/runtime/RouterConfigurationBuilder.js';
import { mockDocumentBaseURI } from '../mocks/dom.js';
-import { browserRouter, createBrowserRouter } from '../mocks/react-router-dom.js';
import { protectRoute } from '../mocks/vaadin-hilla-react-auth.js';
use(chaiLike);
@@ -43,6 +42,10 @@ describe('RouterBuilder', () => {
},
]);
reset = mockDocumentBaseURI('https://example.com/foo');
+ // @ts-expect-error Fake just enough so tests pass
+ globalThis.window = { history: { replaceState: () => {} }, location: '', addEventListener: () => {} };
+ // @ts-expect-error Fake just enough so tests pass
+ globalThis.document.defaultView = globalThis.window;
});
afterEach(() => {
@@ -637,12 +640,6 @@ describe('RouterBuilder', () => {
},
]);
});
-
- it('should not throw when no routes', () => {
- const { routes } = new RouterConfigurationBuilder().withLayout(Server).build();
-
- expect(routes).to.be.like([]);
- });
});
describe('withLayoutSkipping', () => {
@@ -806,28 +803,4 @@ describe('RouterBuilder', () => {
expect(protectRoute).to.have.been.calledWith(test, '/login');
});
});
-
- describe('build', () => {
- it('should build the router', () => {
- const { routes, router } = builder.build();
-
- expect(router).to.equal(browserRouter);
- expect(createBrowserRouter).to.have.been.calledWith(routes, {
- basename: '/foo',
- future: {
- // eslint-disable-next-line camelcase
- v7_fetcherPersist: true,
- // eslint-disable-next-line camelcase
- v7_normalizeFormMethod: true,
- // eslint-disable-next-line camelcase
- v7_partialHydration: true,
- // eslint-disable-next-line camelcase
- v7_relativeSplatPath: true,
- // eslint-disable-next-line camelcase
- v7_skipActionErrorRevalidation: true,
- },
- });
- reset();
- });
- });
});
diff --git a/packages/ts/react-auth/package.json b/packages/ts/react-auth/package.json
index 0befa0b409..32407b8dd5 100644
--- a/packages/ts/react-auth/package.json
+++ b/packages/ts/react-auth/package.json
@@ -51,7 +51,7 @@
"peerDependencies": {
"react": "^18",
"react-dom": "^18",
- "react-router-dom": "^6.28.0"
+ "react-router": "^7"
},
"devDependencies": {
"@esm-bundle/chai": "^4.3.4-fix.0",
@@ -67,6 +67,7 @@
"@types/validator": "^13.11.2",
"@web/test-runner": "^0.19.0",
"chai-dom": "^1.11.0",
+ "react-router": "^7.0.2",
"sinon": "^16.0.0",
"sinon-chai": "^3.7.0",
"typescript": "5.6.2"
diff --git a/packages/ts/react-auth/src/ProtectedRoute.tsx b/packages/ts/react-auth/src/ProtectedRoute.tsx
index de3d0918cb..75e5ff7bec 100644
--- a/packages/ts/react-auth/src/ProtectedRoute.tsx
+++ b/packages/ts/react-auth/src/ProtectedRoute.tsx
@@ -1,6 +1,6 @@
import { useContext, type JSX } from 'react';
-import type { RouteObject } from 'react-router-dom';
-import { type IndexRouteObject, Navigate, type NonIndexRouteObject, useLocation } from 'react-router-dom';
+import type { RouteObject } from 'react-router';
+import { type IndexRouteObject, Navigate, type NonIndexRouteObject, useLocation } from 'react-router';
import { type AccessProps, AuthContext } from './useAuth.js';
type CustomMetadata = Record;
diff --git a/packages/ts/react-auth/test/ProtectedRoute.spec.tsx b/packages/ts/react-auth/test/ProtectedRoute.spec.tsx
index 271d7f34ad..26d0afadec 100644
--- a/packages/ts/react-auth/test/ProtectedRoute.spec.tsx
+++ b/packages/ts/react-auth/test/ProtectedRoute.spec.tsx
@@ -1,6 +1,6 @@
import { expect } from '@esm-bundle/chai';
import { render, waitFor } from '@testing-library/react';
-import { createMemoryRouter, RouterProvider } from 'react-router-dom';
+import { createMemoryRouter, RouterProvider } from 'react-router';
import { configureAuth, protectRoutes, type RouteObjectWithAuth } from '../src';
function TestView({ route }: { route: string }) {
diff --git a/pom.xml b/pom.xml
index 6996af5ca5..463351a027 100644
--- a/pom.xml
+++ b/pom.xml
@@ -75,7 +75,7 @@
2.17.2
5.10.1
4.5.0
- 24.6-SNAPSHOT
+ 24.7-SNAPSHOT
2.0.9
3.3.6
9.3.6