fix: migrate react-router to v8 and patch postcss advisory#113
Merged
Conversation
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
CI's audit gate (
npm audit --audit-level=high --omit=dev) was failing on two advisories:react-router >=7.12.0 <8.3.0. Only fixed in v8.postcss <=8.5.17.Changes
package.jsonreact-router-dom@^7.12.0→react-router@^8.3.0. Thereact-router-dompackage no longer exists in v8; it was only ever a re-export shim to smooth the v6→v7 upgrade.react/react-dom^19.2.0→^19.2.7— required, v8's peer range is>=19.2.7and the tree was resolving 19.2.4.overrides.postcss^8.4.38→^8.5.18. The override already existed but was loose enough to keep resolving 8.5.15; now resolves 8.5.23.31 source files — import specifier rewrite only, no API changes. Every export this app uses (
useNavigate,Navigate,Link,NavLink,Outlet,useLocation,useSearchParams,createBrowserRouter,RouterProvider,useRouteError,isRouteErrorResponse) is exported fromreact-routerroot in v8.The one non-mechanical change is
src/main.tsx, which importsRouterProviderfromreact-router/dom, not the root. Verified against the published v8 package rather than the docs:react-router/domexports onlyRouterProvider,HydratedRouter, and RSC APIs, and itsRouterProvideris the root one pre-wired withReactDOM.flushSync— exactly what v7'sreact-router-domexport was. This preserves existing behavior.No
future.*flags, loaders, actions,meta(), oruseMatches()in this app, so none of v8's other breaking changes apply. Node 22 (CI) and 22.23.1 (Docker) both satisfy v8's>=22.22.0engine requirement.Verification
Run against a clean
npm ci:npm run format:checknpm run lintreact-hook-form'swatch())npm run buildnpm audit --audit-level=high --omit=devNeither advisory appears in the full audit. Remaining findings are dev-only and pre-existing on
main(brace-expansion,fast-uri,js-yamlvia the eslint toolchain — excluded by--omit=dev;esbuildis low, below threshold).Runtime, driven headlessly against the dev server — 15/15:
/app,/app/status,/app/apply,/admin,/admin/all-applicants,/admin/sa/reviews,/admin/sa/walk-in-queue) redirect to//auth/verify,/auth/callback/google) still match and don't fall through*catch-all rendersErrorPage;navigate("/")stays client-side; history back worksNavigation-state semantics were also exercised directly against the installed v8 router core (9/9) —
navigate(path, { state })delivery, andnavigate(path, { replace: true, state: null })clearing state while emitting a new location key so a consuming effect re-runs once and terminates. That matters for thejustSubmittedhandling on #106's status page, which this PR doesn't contain.Not covered
Authenticated surfaces were not exercised in a browser — no session was available. Worth a signed-in click-through on the admin sidebar links, the grading pages'
useSearchParamsreads, and especiallyNavUser's view-switch, which doesrequestAnimationFrame(() => navigate(target))to dodge a Radixpointer-eventsbug and is timing-sensitive against router internals.🤖 Generated with Claude Code