build(web)!: upgrade to react-router v7

Quentin Gliech and Claude Opus 4.6 (1M context) created

replace react-router-dom v6 with react-router v7, updating all
imports from "react-router-dom" to "react-router"

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

Change summary

webui2/package.json                       |  2 
webui2/pnpm-lock.yaml                     | 54 ++++++++++++------------
webui2/src/App.tsx                        |  2 
webui2/src/__generated__/graphql.ts       |  0 
webui2/src/components/bugs/BugRow.tsx     |  2 
webui2/src/components/bugs/Timeline.tsx   |  2 
webui2/src/components/code/CommitList.tsx |  2 
webui2/src/components/code/FileTree.tsx   |  2 
webui2/src/components/layout/Header.tsx   |  2 
webui2/src/components/layout/Shell.tsx    |  2 
webui2/src/lib/repo.tsx                   |  2 
webui2/src/pages/BugDetailPage.tsx        |  2 
webui2/src/pages/CodePage.tsx             |  2 
webui2/src/pages/CommitPage.tsx           |  2 
webui2/src/pages/ErrorPage.tsx            |  2 
webui2/src/pages/NewBugPage.tsx           |  2 
webui2/src/pages/RepoPickerPage.tsx       |  2 
webui2/src/pages/UserProfilePage.tsx      |  2 
18 files changed, 42 insertions(+), 44 deletions(-)

Detailed changes

webui2/package.json 🔗

@@ -30,7 +30,7 @@
     "react": "^19.1.0",
     "react-dom": "^19.1.0",
     "react-markdown": "^10.1.0",
-    "react-router-dom": "^6.28.0",
+    "react-router": "^7.13.2",
     "rehype-autolink-headings": "^7.1.0",
     "rehype-external-links": "^3.0.0",
     "rehype-raw": "^7.0.0",

webui2/pnpm-lock.yaml 🔗

@@ -53,9 +53,9 @@ importers:
       react-markdown:
         specifier: ^10.1.0
         version: 10.1.0(@types/react@19.2.14)(react@19.2.4)
-      react-router-dom:
-        specifier: ^6.28.0
-        version: 6.30.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
+      react-router:
+        specifier: ^7.13.2
+        version: 7.13.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4)
       rehype-autolink-headings:
         specifier: ^7.1.0
         version: 7.1.0
@@ -1275,10 +1275,6 @@ packages:
   '@radix-ui/rect@1.1.1':
     resolution: {integrity: sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==}
 
-  '@remix-run/router@1.23.2':
-    resolution: {integrity: sha512-Ic6m2U/rMjTkhERIa/0ZtXJP17QUi2CbWE7cqx4J58M8aA3QTfW+2UlQ4psvTX9IO1RfNVhK3pcpdjej7L+t2w==}
-    engines: {node: '>=14.0.0'}
-
   '@repeaterjs/repeater@3.0.6':
     resolution: {integrity: sha512-Javneu5lsuhwNCryN+pXH93VPQ8g0dBX7wItHFgYiwQmzE1sVdg5tWHiOgHywzL2W21XQopa7IwIEnNbmeUJYA==}
 
@@ -1665,6 +1661,10 @@ packages:
   convert-source-map@2.0.0:
     resolution: {integrity: sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg==}
 
+  cookie@1.1.1:
+    resolution: {integrity: sha512-ei8Aos7ja0weRpFzJnEA9UHJ/7XQmqglbRwnf2ATjcB9Wq874VKH9kfjjirM6UhU2/E5fFYadylyhFldcqSidQ==}
+    engines: {node: '>=18'}
+
   cosmiconfig@8.3.6:
     resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==}
     engines: {node: '>=14'}
@@ -2626,18 +2626,15 @@ packages:
       '@types/react':
         optional: true
 
-  react-router-dom@6.30.3:
-    resolution: {integrity: sha512-pxPcv1AczD4vso7G4Z3TKcvlxK7g7TNt3/FNGMhfqyntocvYKj+GCatfigGDjbLozC4baguJ0ReCigoDJXb0ag==}
-    engines: {node: '>=14.0.0'}
-    peerDependencies:
-      react: '>=16.8'
-      react-dom: '>=16.8'
-
-  react-router@6.30.3:
-    resolution: {integrity: sha512-XRnlbKMTmktBkjCLE8/XcZFlnHvr2Ltdr1eJX4idL55/9BbORzyZEaIkBFDhFGCEWBBItsVrDxwx3gnisMitdw==}
-    engines: {node: '>=14.0.0'}
+  react-router@7.13.2:
+    resolution: {integrity: sha512-tX1Aee+ArlKQP+NIUd7SE6Li+CiGKwQtbS+FfRxPX6Pe4vHOo6nr9d++u5cwg+Z8K/x8tP+7qLmujDtfrAoUJA==}
+    engines: {node: '>=20.0.0'}
     peerDependencies:
-      react: '>=16.8'
+      react: '>=18'
+      react-dom: '>=18'
+    peerDependenciesMeta:
+      react-dom:
+        optional: true
 
   react-style-singleton@2.2.3:
     resolution: {integrity: sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ==}
@@ -2760,6 +2757,9 @@ packages:
   sentence-case@3.0.4:
     resolution: {integrity: sha512-8LS0JInaQMCRoQ7YUytAo/xUu5W2XnQxV2HI/6uM6U7CITS1RqPElr30V6uIqyMKM9lJGRVFy5/4CuzcixNYSg==}
 
+  set-cookie-parser@2.7.2:
+    resolution: {integrity: sha512-oeM1lpU/UvhTxw+g3cIfxXHyJRc/uidd3yK1P242gzHds0udQBYzs3y8j4gCCW+ZJ7ad0yctld8RYO+bdurlvw==}
+
   shell-quote@1.8.3:
     resolution: {integrity: sha512-ObmnIF4hXNg1BqhnHmgbDETF8dLPCggZWBjkQfhZpbszZnYur5DUljTcCHii5LC3J5E0yeO/1LIMyH+UvHQgyw==}
     engines: {node: '>= 0.4'}
@@ -4279,8 +4279,6 @@ snapshots:
 
   '@radix-ui/rect@1.1.1': {}
 
-  '@remix-run/router@1.23.2': {}
-
   '@repeaterjs/repeater@3.0.6': {}
 
   '@rolldown/binding-android-arm64@1.0.0-rc.12':
@@ -4620,6 +4618,8 @@ snapshots:
 
   convert-source-map@2.0.0: {}
 
+  cookie@1.1.1: {}
+
   cosmiconfig@8.3.6(typescript@6.0.2):
     dependencies:
       import-fresh: 3.3.1
@@ -5787,17 +5787,13 @@ snapshots:
     optionalDependencies:
       '@types/react': 19.2.14
 
-  react-router-dom@6.30.3(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
+  react-router@7.13.2(react-dom@19.2.4(react@19.2.4))(react@19.2.4):
     dependencies:
-      '@remix-run/router': 1.23.2
+      cookie: 1.1.1
       react: 19.2.4
+      set-cookie-parser: 2.7.2
+    optionalDependencies:
       react-dom: 19.2.4(react@19.2.4)
-      react-router: 6.30.3(react@19.2.4)
-
-  react-router@6.30.3(react@19.2.4):
-    dependencies:
-      '@remix-run/router': 1.23.2
-      react: 19.2.4
 
   react-style-singleton@2.2.3(@types/react@19.2.14)(react@19.2.4):
     dependencies:
@@ -5968,6 +5964,8 @@ snapshots:
       tslib: 2.8.1
       upper-case-first: 2.0.2
 
+  set-cookie-parser@2.7.2: {}
+
   shell-quote@1.8.3: {}
 
   signal-exit@4.1.0: {}

webui2/src/App.tsx 🔗

@@ -1,4 +1,4 @@
-import { createBrowserRouter, RouterProvider } from "react-router-dom";
+import { createBrowserRouter, RouterProvider } from "react-router";
 
 import { Shell } from "@/components/layout/Shell";
 import { RepoShell } from "@/lib/repo";

webui2/src/components/bugs/BugRow.tsx 🔗

@@ -1,6 +1,6 @@
 import { formatDistanceToNow } from "date-fns";
 import { MessageSquare, CircleDot, CircleCheck } from "lucide-react";
-import { Link } from "react-router-dom";
+import { Link } from "react-router";
 
 import { Status } from "@/__generated__/graphql";
 

webui2/src/components/bugs/Timeline.tsx 🔗

@@ -1,7 +1,7 @@
 import { formatDistanceToNow } from "date-fns";
 import { Tag, GitPullRequestClosed, Pencil, CircleDot } from "lucide-react";
 import { useState } from "react";
-import { Link } from "react-router-dom";
+import { Link } from "react-router";
 
 import {
   Status,

webui2/src/components/code/CommitList.tsx 🔗

@@ -5,7 +5,7 @@ import { gql, useQuery } from "@apollo/client";
 import { formatDistanceToNow } from "date-fns";
 import { GitCommit } from "lucide-react";
 import { useState } from "react";
-import { Link } from "react-router-dom";
+import { Link } from "react-router";
 
 import { Button } from "@/components/ui/button";
 import { Skeleton } from "@/components/ui/skeleton";

webui2/src/components/code/FileTree.tsx 🔗

@@ -1,6 +1,6 @@
 import { formatDistanceToNow } from "date-fns";
 import { Folder, File } from "lucide-react";
-import { Link } from "react-router-dom";
+import { Link } from "react-router";
 
 import type { GitTreeEntry } from "@/__generated__/graphql";
 import { Skeleton } from "@/components/ui/skeleton";

webui2/src/components/layout/Header.tsx 🔗

@@ -7,7 +7,7 @@
 // action when logged in.
 
 import { Bug, Plus, Sun, Moon, LogIn, LogOut } from "lucide-react";
-import { Link, useMatch, NavLink } from "react-router-dom";
+import { Link, useMatch, NavLink } from "react-router";
 
 import { Avatar, AvatarFallback, AvatarImage } from "@/components/ui/avatar";
 import { Button } from "@/components/ui/button";

webui2/src/lib/repo.tsx 🔗

@@ -7,7 +7,7 @@
 //   - Pass the slug as `ref` to all GraphQL repository queries.
 
 import { createContext, useContext } from "react";
-import { useParams, Outlet } from "react-router-dom";
+import { useParams, Outlet } from "react-router";
 
 const RepoContext = createContext<string | null>(null);
 

webui2/src/pages/BugDetailPage.tsx 🔗

@@ -1,6 +1,6 @@
 import { formatDistanceToNow } from "date-fns";
 import { ArrowLeft } from "lucide-react";
-import { useParams, Link } from "react-router-dom";
+import { useParams, Link } from "react-router";
 
 import { useBugDetailQuery } from "@/__generated__/graphql";
 import { CommentBox } from "@/components/bugs/CommentBox";

webui2/src/pages/CodePage.tsx 🔗

@@ -4,7 +4,7 @@
 import { gql, useQuery } from "@apollo/client";
 import { AlertCircle, GitCommit } from "lucide-react";
 import { useEffect } from "react";
-import { useSearchParams } from "react-router-dom";
+import { useSearchParams } from "react-router";
 
 import type { GitRef, GitTreeEntry, GitBlob, GitLastCommit } from "@/__generated__/graphql";
 import { CodeBreadcrumb } from "@/components/code/CodeBreadcrumb";

webui2/src/pages/CommitPage.tsx 🔗

@@ -4,7 +4,7 @@
 import { gql, useQuery } from "@apollo/client";
 import { format } from "date-fns";
 import { ArrowLeft, GitCommit } from "lucide-react";
-import { Link, useParams, useNavigate } from "react-router-dom";
+import { Link, useParams, useNavigate } from "react-router";
 
 import { FileDiffView } from "@/components/code/FileDiffView";
 import { Skeleton } from "@/components/ui/skeleton";

webui2/src/pages/ErrorPage.tsx 🔗

@@ -3,7 +3,7 @@
 // Application Error!" screen.
 
 import { AlertTriangle } from "lucide-react";
-import { useRouteError, isRouteErrorResponse, Link } from "react-router-dom";
+import { useRouteError, isRouteErrorResponse, Link } from "react-router";
 
 import { Button } from "@/components/ui/button";
 

webui2/src/pages/NewBugPage.tsx 🔗

@@ -1,6 +1,6 @@
 import { ArrowLeft } from "lucide-react";
 import { useState } from "react";
-import { useNavigate, Link } from "react-router-dom";
+import { useNavigate, Link } from "react-router";
 
 import { useBugCreateMutation } from "@/__generated__/graphql";
 import { Markdown } from "@/components/content/Markdown";

webui2/src/pages/RepoPickerPage.tsx 🔗

@@ -3,7 +3,7 @@
 
 import { GitFork, FolderOpen, AlertCircle } from "lucide-react";
 import { useEffect } from "react";
-import { Link, useNavigate } from "react-router-dom";
+import { Link, useNavigate } from "react-router";
 
 import { useRepositoriesQuery } from "@/__generated__/graphql";
 import { Skeleton } from "@/components/ui/skeleton";

webui2/src/pages/UserProfilePage.tsx 🔗

@@ -17,7 +17,7 @@ import {
   ChevronRight,
 } from "lucide-react";
 import { useState } from "react";
-import { useParams, Link } from "react-router-dom";
+import { useParams, Link } from "react-router";
 
 import { Status, useUserProfileQuery } from "@/__generated__/graphql";
 import { LabelBadge } from "@/components/bugs/LabelBadge";