mcpField
C
clerk-react-router-patterns

clerk-react-router-patterns

github.com/clerk開発8915.6k 回インストール今日更新
リポジトリ

clerk-react-router-patterns について

React Router v7/v8 プロジェクト向けの Clerk 認証スキルです。ミドルウェア、ローダー、アクション、クライアントコンポーネントで認証を扱う開発者に向け、サーバーからクライアントへの認証状態の受け渡しやバージョン別設定を説明します。

主な機能

  1. 01ローダーとアクションでの認証
  2. 02ミドルウェアとルート認証状態の受け渡し
  3. 03保護ルートとリダイレクト
  4. 04クライアント認証フック
  5. 05React Router v7/v8 の設定案内

活用シーン

  1. 01ローダーでユーザー別データを取得
  2. 02アクション処理前にユーザーを検証
  3. 03ルートを保護し未認証ユーザーを転送
  4. 04SSR アプリでクライアントに認証状態を提供

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/clerk/skills --skill clerk-react-router-patterns

インストール後、Claude Code で/clerk-react-router-patternsを入力して読み込まれたか確認します。

同梱ファイル

SKILL.md と一緒にインストールされる参考資料やスクリプト。

evals/
evals.json
references/
loaders-actions.md
protected-routes.md
ssr-auth.md
templates/react-router-basic-auth/
package.json
react-router.config.ts
vite.config.ts
templates/react-router-basic-auth/app/
app.css
root.tsx
routes.ts
templates/react-router-basic-auth/app/routes/
home.tsx

詳細

React Routerのパターン

SDK:@clerk/react-router v3.5+。React Router v7.9+およびv8に対応しています。

必要な情報を選んでください

タスクリファレンス
ローダーとアクションでの認証references/loaders-actions.md
保護されたルートとリダイレクトreferences/protected-routes.md
SSRのユーザーデータとセッションreferences/ssr-auth.md

React Router v7とv8の違い

セットアップの前に、インストールされているreact-routerのメジャーバージョンを確認してください。設定が異なります。

v7.9+v8+
ミドルウェアAPIオプトイン:react-router.config.tsでfuture: { v8_middleware: true }を設定常に有効です。フラグは設定しないでください(v8では削除されています)
ssr.noExternalの回避策(下記)不要必須

最小限のセットアップ

1. vite.config.ts(v8のみ — 必須)

React Router v8には、開発環境と本番環境で異なる条件付きエクスポートが含まれています。react-router devでは、 ViteがSSR用に@clerk/react-routerを外部化するため、Nodeはreact-routerの本番ビルドを解決する一方で、 アプリのコードは開発ビルドを取得します。その結果、モジュールインスタンスとRouterコンテキストがそれぞれ2つになり、 すべてのリクエストがSSR中に次のエラーで失敗します。

Error: useNavigate() may be used only in the context of a <Router> component.

npm ls react-routerでコピーが1つだけ表示されても、問題がないとは限りません。 重複はインストールされたコピーごとではなく、エクスポート条件ごとに発生します。重複インストールを調べるのではなく、回避策を追加してください(上流のissue: https://github.com/remix-run/react-router/issues/15232)。

import { reactRouter } from '@react-router/dev/vite'
import { defineConfig } from 'vite'

export default defineConfig({
  plugins: [reactRouter()],
  ssr: {
    noExternal: ['@clerk/react-router'],
  },
})
2. root.tsx
import { Outlet } from 'react-router'
import { rootAuthLoader, clerkMiddleware } from '@clerk/react-router/server'
import { ClerkProvider } from '@clerk/react-router'
import type { Route } from './+types/root'

export const middleware: Route.MiddlewareFunction[] = [clerkMiddleware()]

export async function loader(args: Route.LoaderArgs) {
  return rootAuthLoader(args)
}

export default function App({ loaderData }: Route.ComponentProps) {
  return (
    <ClerkProvider loaderData={loaderData}>
      <Outlet />
    </ClerkProvider>
  )
}

@clerk/react-routerにはClerkApp HOCはありません(これは@clerk/remixのAPIでした)。 デフォルトエクスポート内で<ClerkProvider loaderData={loaderData}>をレンダリングし、 ルートルートのloaderDataを渡してください。

3. react-router.config.ts(v7のみ)
import type { Config } from '@react-router/dev/config'

export default {
  future: {
    v8_middleware: true,
  },
} satisfies Config

v8ではfutureブロック全体を省略してください。フラグはもう存在しません。

必須:rootAuthLoaderはroot.tsxのloaderで呼び出す必要があります。これがないと、ネストされたloaderでgetAuthが例外をスローします。

基本的な考え方

React Router v7/v8は、ミドルウェアとローダーのパイプラインを使用します。Clerkは両方のレイヤーに組み込まれます。

  • ミドルウェア(clerkMiddleware()) — すべてのリクエストで実行され、認証情報をコンテキストに付与します
  • rootAuthLoader — Clerkの状態をクライアントに渡すため、root.tsxで必須です
  • getAuth(args) — 現在のユーザーを取得するため、任意のloader/action内で呼び出します
Request → clerkMiddleware() → rootAuthLoader → page loader → component
                 ↓                   ↓               ↓
           attaches auth      injects state     getAuth(args)
           to context         to response       reads context

ローダーでの認証

import { getAuth } from '@clerk/react-router/server'
import type { Route } from './+types/dashboard'

export async function loader(args: Route.LoaderArgs) {
  const { userId } = await getAuth(args)
  if (!userId) throw redirect('/sign-in')

  const data = await fetchUserData(userId)
  return { data }
}

アクションでの認証

import { getAuth } from '@clerk/react-router/server'

export async function action(args: Route.ActionArgs) {
  const { userId, orgId } = await getAuth(args)
  if (!userId) throw new Response('Unauthorized', { status: 401 })

  const formData = await args.request.formData()
  await saveData(userId, orgId, formData)
  return redirect('/dashboard')
}

クライアントコンポーネント

import { useAuth, useUser } from '@clerk/react-router'

export function Profile() {
  const { userId, isSignedIn } = useAuth()
  const { user } = useUser()
  if (!isSignedIn) return null
  return <p>{user?.firstName}</p>
}

組織の切り替え

import { OrganizationSwitcher } from '@clerk/react-router'

export function Nav() {
  return <OrganizationSwitcher afterSelectOrganizationUrl="/dashboard" />
}
export async function loader(args: Route.LoaderArgs) {
  const { userId, orgId } = await getAuth(args)
  if (!userId) throw redirect('/sign-in')
  if (!orgId) throw redirect('/select-org')

  return { data: await fetchOrgData(orgId) }
}

よくある問題

症状原因修正方法
v8の開発環境でSSR中にClerkProviderからuseNavigate() may be used only in the context of a <Router>がスローされるViteの開発時SSRが@clerk/react-routerを外部化するため、アプリが開発ビルドを使用する一方で、react-routerの本番ビルドが読み込まれ、Routerコンテキストが2つになります。npm lsでコピーが1つだけ表示されても、問題がないとは限りません。vite.config.tsにssr: { noExternal: ['@clerk/react-router'] }を追加してください。v7にダウングレードしないでください
ビルドエラー:ClerkAppはエクスポートされていません@clerk/react-routerにClerkAppは存在しませんroot.tsxのデフォルトエクスポートで<ClerkProvider loaderData={loaderData}>を使用してください
clerkMiddleware() not detectedミドルウェアがありません(またはv7でv8_middlewareのfutureフラグがありません)ルートからmiddleware = [clerkMiddleware()]をエクスポートしてください。v7ではfuture: { v8_middleware: true }も設定してください
不明なfutureフラグのエラー/警告(v8)アップグレード後もreact-router.config.tsにv8_middlewareフラグが残っていますfuture.v8_middlewareの項目を削除してください。v8ではミドルウェアは常に有効です
getAuthが空のuserIdを返すrootAuthLoaderが呼び出されていませんroot.tsxのloaderでrootAuthLoader(args)を呼び出してください
リダイレクトが無限に繰り返されるリダイレクト先も保護されています保護チェックから/sign-inを除外してください
actionでredirectが機能しないthrow redirect()ではなくResponseを使用していますreact-routerのthrow redirect('/path')を使用してください

Import Map

WhatImport From
getAuth@clerk/react-router/server
rootAuthLoader@clerk/react-router/server
clerkMiddleware@clerk/react-router/server
ClerkProvider@clerk/react-router
useAuth, useUser@clerk/react-router
OrganizationSwitcher@clerk/react-router

See Also

  • clerk-setup - Initial Clerk install
  • clerk-custom-ui - Custom flows & appearance
  • clerk-orgs - B2B organizations

Docs

React Router SDK

コメント