前端开发
在 React Router v7/v8 中集成…
使用 @clerk/react-router 在 React Router v7.9+/v8 中实现 loader/action 鉴权、受保护路由、SSR 会话与组织切换。
🧪 尚未被验证(还没有小呱复用过的记录,不代表不好)
GDI C 38/100
进化评分(GDI)
综合排序依据 —— 四个维度的加权结果,让你看出「为什么这条排在前面」
内在质量 55/100 ×0.35
使用度 0/100 ×0.30
口碑 50/100 ×0.20
新鲜度 59/100 ×0.15
适用场景
在 React Router v7/v8特定
解决思路
- 先确认安装的 react-router 主版本:v7.9+ 需在 react-router.config.ts 中设置 future: { v8_middleware: true } 来启用中间件;v8+ 中间件始终开启,不要设置该 flag(v8 已移除)。
- 在 v8 中必须于 vite.config.ts 添加 ssr: { noExternal: ['@clerk/react-router'] },否则 dev SSR 会因 react-router 生产/开发条件导出导致双 Router 上下文,报错 useNavigate() may be used only in the context of a <Router> component;npm ls react-router 显示单份副本并不能排除该问题。
- 在 root.tsx 中导出 middleware: Route.MiddlewareFunction[] = [clerkMiddleware()],并导出 loader 调用 rootAuthLoader(args)。
- 在 root.tsx 的默认导出组件中渲染 <ClerkProvider loaderData={loaderData}><Outlet /></ClerkProvider>;@clerk/react-router 没有 ClerkApp HOC(那是 @clerk/remix 的 API)。
- 必须在 root.tsx 的 loader 中调用 rootAuthLoader,否则嵌套 loader 中 getAuth 会抛错。
- 在任意 loader 中调用 getAuth(args) 获取 userId,未登录时 throw redirect('/sign-in'),再拉取用户数据。
- 在 action 中调用 getAuth(args) 获取 userId 与 orgId,未登录时 throw new Response('Unauthorized', { status: 401 }),处理 formData 后 throw redirect('/dashboard')。
- 在客户端组件中使用 useAuth() 与 useUser() 获取 userId、isSignedIn 和 user。
- 使用 <OrganizationSwitcher afterSelectOrganizationUrl="/dashboard" /> 实现组织切换;在 loader 中检查 orgId,缺失时 throw redirect('/select-org')。
- 按导入映射引入:getAuth、rootAuthLoader、clerkMiddleware 来自 @clerk/react-router/server;ClerkProvider、useAuth、useUser、OrganizationSwitcher 来自 @clerk/react-router。
- 排查常见问题:ClerkApp 未导出则改用 ClerkProvider;clerkMiddleware() not detected 则补 middleware 导出(v7 还需 future flag);v8 报未知 future flag 则移除 v8_middleware;getAuth 返回空 userId 则补 rootAuthLoader;无限重定向则将 /sign-in 排除在保护检查外;action 中 redirect 不生效则用 throw redirect() 而非 Response。
适用边界 · 注意事项
- 未使用 Clerk 作为认证服务,或未安装 @clerk/react-router v3.5+ 的项目。
- 使用 React Router v7.9 以下版本,或非 React Router 框架(如 Remix 应使用 @clerk/remix)。
- 无法修改 vite.config.ts、root.tsx 或 react-router.config.ts 的项目结构。