chore: React Router v7.9.1 へのアップデートと Middleware API の変更対応#25
Conversation
WalkthroughReplaces deprecated userContext with a new authContext and updates middleware/types to stable React Router APIs. Renames client middleware exports, aligns config flags with v8_middleware, bumps dependencies and tooling (React Router, Biome, Tailwind, etc.), adjusts Prettier CLI flags, and updates Biome schema and includes. Changes
Sequence Diagram(s)sequenceDiagram
autonumber
participant U as User
participant R as Router
participant MW as Middleware
participant C as Context
participant Rt as Route (loader/action)
U->>R: Navigates / requests
R->>MW: Invoke client/server middleware
MW->>C: context.set(authContext, user)
Note right of C: Stores AppUser|null under authContext
R->>Rt: Dispatch loader/action
Rt->>C: context.get(authContext)
C-->>Rt: AppUser|null
Rt-->>R: Response / redirect
R-->>U: Render page
Estimated code review effort🎯 2 (Simple) | ⏱️ ~12 minutes Possibly related PRs
Poem
Pre-merge checks and finishing touches✅ Passed checks (3 passed)
✨ Finishing touches
🧪 Generate unit tests
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
Visit the preview URL for this PR (updated for commit ff8492f): https://remix-spa-example--pr25-chore-bump-jfswclvx.web.app (expires Sat, 20 Sep 2025 13:39:27 GMT) 🔥 via Firebase Hosting GitHub Action 🌎 Sign: 48e666b485811f0b1bcd4fa4838b32a205a3ce05 |
There was a problem hiding this comment.
Actionable comments posted: 1
Caution
Some comments are outside the diff and can’t be posted inline due to platform limitations.
⚠️ Outside diff range comments (2)
package.json (1)
65-67: Update package.json engines.node to >=20.19.0Vite 7.x needs Node 20.19+ (React Router v7 requires Node 20+), so
"node": ">=18.0.0"is insufficient — change package.json (lines 65–67) to require Node >=20.19.0 (or bump to a recent Node 22/24 LTS).app/routes/$handle+/_index/route.tsx (1)
39-45: Return proper HTTP status instead of throwing a generic Error in clientActionAlign with other routes and avoid 500s by using 401/403.
Apply:
- const user = context.get(authContext) - if (user?.handle !== handle) { - throw new Error('Unauthorized') - } + const user = context.get(authContext) + if (!user) { + throw data(null, { status: 401 }) + } + if (user.handle !== handle) { + throw data(null, { status: 403 }) + }
🧹 Nitpick comments (6)
app/routes/welcome+/_layout/route.ts (1)
4-4: (Optional) Add a type guard for middleware arrayAnnotating helps catch accidental non-middleware entries.
-export const clientMiddleware = [onBoardingAuthMiddleware] +export const clientMiddleware = [onBoardingAuthMiddleware] satisfies Array<import('react-router').MiddlewareFunction>biome.json (1)
2-5: Check Biome files scope vs build artifactsWith
"files.includes": ["**", "!app/styles/globals.css"], Biome could scan build outputs unless ignored elsewhere. Consider excluding common artifacts here too for speed."files": { - "includes": ["**", "!app/styles/globals.css"] + "includes": ["**", "!app/styles/globals.css", "!**/build", "!**/dist", "!**/coverage"] },package.json (1)
31-31: Pin radix-ui in package.json — don't use "latest"package.json (line 31) currently has "radix-ui": "latest". pnpm-lock.yaml shows it resolved to 1.4.3 — change to a pinned semver (e.g. ^1.4.3 or 1.4.3) to avoid surprise upgrades.
File: package.json
Lines: 31-31"radix-ui": "latest",app/middlewares/auth-context.ts (1)
1-4: (Nit) Add a brief doc commentImproves discoverability in editors.
-import { createContext } from 'react-router' +import { createContext } from 'react-router' import type { AppUser } from '~/services/auth' -export const authContext = createContext<AppUser | null>() +/** + * Authenticated user context for middleware → route data flow. + * Null when unauthenticated. + */ +export const authContext = createContext<AppUser | null>()app/routes/welcome+/create_account/route.tsx (1)
29-33: Handle missing user with redirect (graceful failure path)This route should be behind onboarding auth, but a defensive redirect avoids a 500 if context isn’t set.
Apply:
- if (!user) { - throw new Error('システムエラー: ユーザ情報がありません') - } + if (!user) { + throw redirect('/') + }app/routes/$handle+/posts.$id.delete/route.tsx (1)
24-29: Differentiate 401 vs 403 for clearer auth semanticsReturn 401 when unauthenticated and 403 when authenticated but not the owner.
Apply:
- const user = context.get(authContext) - if (user?.handle !== handle) { - // 本人でなければ削除できない - throw data(null, { status: 401 }) - } + const user = context.get(authContext) + if (!user) { + throw data(null, { status: 401 }) + } + if (user.handle !== handle) { + // 本人でなければ削除できない + throw data(null, { status: 403 }) + }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
⛔ Files ignored due to path filters (1)
pnpm-lock.yamlis excluded by!**/pnpm-lock.yaml
📒 Files selected for processing (15)
.vscode/settings.json(1 hunks)app/middlewares/auth-context.ts(1 hunks)app/middlewares/on-boarding-auth-middleware.ts(1 hunks)app/middlewares/optional-auth-middleware.ts(1 hunks)app/middlewares/user-context.ts(0 hunks)app/routes/$handle+/_index/route.tsx(3 hunks)app/routes/$handle+/_layout/route.tsx(1 hunks)app/routes/$handle+/posts.$id._index/route.tsx(2 hunks)app/routes/$handle+/posts.$id.delete/route.tsx(2 hunks)app/routes/$handle+/posts.$id.edit/route.tsx(3 hunks)app/routes/welcome+/_layout/route.ts(1 hunks)app/routes/welcome+/create_account/route.tsx(2 hunks)biome.json(1 hunks)package.json(1 hunks)react-router.config.ts(1 hunks)
💤 Files with no reviewable changes (1)
- app/middlewares/user-context.ts
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: coji
PR: coji/remix-spa-example#8
File: app/routes/auth+/sign_out/route.tsx:1-1
Timestamp: 2025-02-19T12:11:06.825Z
Learning: React Router v7.2 introduced the href utility for type-safe routing, which should be imported from 'react-router' instead of 'remix-run/react'.
📚 Learning: 2025-02-19T12:11:06.825Z
Learnt from: coji
PR: coji/remix-spa-example#8
File: app/routes/auth+/sign_out/route.tsx:1-1
Timestamp: 2025-02-19T12:11:06.825Z
Learning: React Router v7.2 introduced the href utility for type-safe routing, which should be imported from 'react-router' instead of 'remix-run/react'.
Applied to files:
app/middlewares/on-boarding-auth-middleware.ts
🧬 Code graph analysis (10)
app/routes/$handle+/posts.$id._index/route.tsx (1)
app/middlewares/auth-context.ts (1)
authContext(4-4)
app/middlewares/auth-context.ts (1)
app/services/auth.ts (1)
AppUser(18-20)
app/routes/welcome+/_layout/route.ts (2)
app/routes/$handle+/_layout/route.tsx (1)
clientMiddleware(5-5)app/middlewares/on-boarding-auth-middleware.ts (1)
onBoardingAuthMiddleware(5-17)
app/routes/$handle+/posts.$id.delete/route.tsx (1)
app/middlewares/auth-context.ts (1)
authContext(4-4)
app/routes/$handle+/_layout/route.tsx (2)
app/routes/welcome+/_layout/route.ts (1)
clientMiddleware(4-4)app/middlewares/optional-auth-middleware.ts (1)
optionalAuthMiddleware(5-12)
app/routes/welcome+/create_account/route.tsx (1)
app/middlewares/auth-context.ts (1)
authContext(4-4)
app/routes/$handle+/posts.$id.edit/route.tsx (1)
app/middlewares/auth-context.ts (1)
authContext(4-4)
app/routes/$handle+/_index/route.tsx (1)
app/middlewares/auth-context.ts (1)
authContext(4-4)
app/middlewares/optional-auth-middleware.ts (2)
app/services/auth.ts (1)
isAuthenticated(107-138)app/middlewares/auth-context.ts (1)
authContext(4-4)
app/middlewares/on-boarding-auth-middleware.ts (2)
app/services/auth.ts (1)
requireAuth(146-151)app/middlewares/auth-context.ts (1)
authContext(4-4)
🔇 Additional comments (20)
react-router.config.ts (2)
6-6: Correct flag rename to v8_middlewareThe migration from unstable_middleware → v8_middleware matches the v7→v8 middleware API stabilization. LGTM.
6-8: Sweep repo for leftover unstable APIsripgrep returned no matches; confirm there are no remaining usages of unstable_clientMiddleware, unstable_createContext, or middlewares/user-context — re-run the searches or manually verify (e.g. rg -nP '\bunstable_clientMiddleware\b|\bunstable_createContext\b' && rg -nP 'middlewares/(user-context)').
app/routes/welcome+/_layout/route.ts (1)
4-4: Export rename to clientMiddleware is consistent with v8 middleware APIGood alignment with the stable API.
.vscode/settings.json (1)
14-14: Switch to source.fixAll.biome is correctMatches Biome’s recommended code action. LGTM.
package.json (1)
11-12: Prettier 3.6.2 supports --experimental-cli; handle cache in CIVerified: Prettier 3.6.x added the experimental CLI and 3.6.2 supports --experimental-cli and it works with --cache.
- Cache keys do NOT include plugin versions — clear the cache (or disable cache) after updating Prettier plugins to avoid stale formatting.
- Default cache: ./node_modules/.cache/prettier/.prettier-cache (override with --cache-location).
- Running Prettier without --cache will delete the cache; combining --cache with commands like --list-different can produce inconsistent/stale results — ensure CI clears/refreshes the cache before check runs or avoid --cache for deterministic CI checks.
File: package.json lines 11–12.
app/routes/$handle+/posts.$id._index/route.tsx (3)
7-7: authContext migration looks correctSwapping to
authContextand reading viacontext.get(authContext)is consistent with the new middleware API.Also applies to: 19-21
3-3: Nice: href imported from react-routerMatches the prior learning to use the typed
hreffromreact-router.
29-49: Server-side authorization already enforced — original concern is incorrectapp/routes/$handle+/posts.$id.edit/route.tsx — clientLoader and clientAction call context.get(authContext) and throw 403 when user?.handle !== handle; app/routes/$handle+/posts.$id.delete/route.tsx — clientAction checks user?.handle !== handle and throws 401.
Likely an incorrect or invalid review comment.
app/middlewares/auth-context.ts (1)
4-4: Dedicated authContext establishedClean, typed context for
AppUser | null. LGTM.app/routes/$handle+/_layout/route.tsx (1)
5-5: Export rename to clientMiddleware is correctConsistent with the v8 middleware API; no behavior change. LGTM.
app/routes/$handle+/_index/route.tsx (2)
16-16: authContext import looks goodMigration to the stable context is correct.
29-33: Context read in loader is correctNull-safe usage and downstream isAuthor calculation are fine.
app/routes/welcome+/create_account/route.tsx (1)
8-8: authContext import migration is correctMatches the new context module.
app/routes/$handle+/posts.$id.delete/route.tsx (1)
14-14: authContext import migration is correctConsistent with the middleware change.
app/routes/$handle+/posts.$id.edit/route.tsx (3)
13-13: authContext import migration is correctMove to stable createContext usage is appropriate.
35-43: Loader auth check is correctUsing 403 for “not your post” is appropriate; existence checks follow correctly.
51-56: Action auth check mirrors loader appropriatelyConsistent 403 on handle mismatch; subsequent updates use user.uid safely.
app/middlewares/optional-auth-middleware.ts (1)
1-12: Middleware API migration looks correct
- Imports the stable MiddlewareFunction type.
- Stores user under authContext via context.set; compatible with downstream context.get calls.
app/middlewares/on-boarding-auth-middleware.ts (2)
1-4: Correct: use href from react-router and stable MiddlewareFunctionMatches our prior learning to import href from 'react-router'.
10-16: LGTM — config and route exports align; one check inconclusive
- react-router.config.ts contains v8_middleware: true (line 6).
- app/routes/welcome+/_layout/route.ts imports onBoardingAuthMiddleware (line 1) and exports clientMiddleware = [onBoardingAuthMiddleware] (line 4).
- ripgrep reported "No files were searched" for the unstable_clientMiddleware check — re-run a plain search for "unstable_clientMiddleware" to confirm no remaining usages.
React Router を
v7.7.1からv7.9.1へアップデートし、それに伴う Middleware API の破壊的変更に対応しました。また、関連する各種依存パッケージも最新版に更新しています。
主な変更点
React Router のアップデート
react-router,react-router-dom,@react-router/devなどをv7.9.1に更新しました。Middleware API の変更対応
react-router.config.tsのunstable_middlewareフラグをv8_middlewareに変更しました。route.ts,route.tsx) のunstable_clientMiddlewareをclientMiddlewareにリネームしました。unstable_createContextをreact-routerから import する安定版のcreateContextに置き換えました。userContextからauthContextに変更し、役割を明確化しました。依存パッケージの更新
pnpm updateを実行し、Vite, TypeScript, Biome, Firebase 関連など、プロジェクト全体の依存関係を更新しました。設定ファイルの更新
.vscode/settings.json: Biome の設定をquickfix.biomeからsource.fixAll.biomeに更新しました。biome.json: スキーマバージョンを更新し、globals.cssを対象外に設定しました。Summary by CodeRabbit
New Features
Refactor
Chores