こんにちは。
前回に引き続き、webアプリを開発していきましょう。
環境構築は終わったので、次は認証をセットアップして、ユーザー登録・ログイン機能を実装していきましょう。
Clerkのセットアップ(認証機能)
認証機能を実装するにあたって、Clerkというサービスを利用します。
Clerkは認証(ログイン・サインアップ)を簡単に実装できるサービスです。
- Clerkアカウントを作成
まず、Clerkの公式サイト にアクセスし、アカウントを作成してください。
(GoogleログインでもOKです)
- 新しいプロジェクトを作成
- 「Create Application」 をクリック
- 「Name your application」 に my-app など適当な名前を入力
- 「Create Application」 を押す
- ClerkのAPIキーを取得
- ダッシュボードの 「API Keys」 タブを開く
- 「Publishable key」 の値をコピー(例:pk_test_XXXXXXXXXXXXXXXX)
- 「Secret key」 の値もコピー(例:XXXXXXXXXXXXXXXX)
この2つを .env.local に設定します。
作成したアプリのフォルダをVSCodeで開き、Next.js プロジェクトのルートに .env.local を作成してください。

こんな感じです。MY-APPの右のボタンからファイルを作成できるので、.env.localと名付けて下さい。
階層構造がズレるので、srcやpublicフォルダの中に入れないように!
- .env.local にAPIキーを追加
.env.local を開き、先ほど取得した以下の内容を入力して下さい。
NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY=pk_test_XXXXXXXXXXXXXXXX
CLERK_SECRET_KEY=XXXXXXXXXXXXXXXX
(pk_test_XXXXXXXXXXXXXXXX と XXXXXXXXXXXXXXXX は、実際にClerkで取得した値に変更してください)
この2つのキーは Clerkの認証情報 であり、
- NEXT_PUBLIC_CLERK_PUBLISHABLE_KEY → フロントエンド用(公開)
- CLERK_SECRET_KEY → バックエンド用(非公開)
になります。
- Clerkのパッケージをインストール
ターミナルで以下のコマンドを実行します。
npm install @clerk/nextjs@latest
- ClerkをNext.jsに設定
src/app/layout.tsx を開いて、以下のように編集してください。
import { ClerkProvider } from "@clerk/nextjs";
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
return (
<ClerkProvider>
<html lang="ja">
<body>{children}</body>
</html>
</ClerkProvider>
);
}
これは何をしている?(クリックで展開)
1️⃣ Clerkの認証情報をアプリ全体に提供
import { ClerkProvider } from "@clerk/nextjs";
- ClerkProvider は Clerkの認証情報をアプリ全体で利用できるようにするためのプロバイダー(コンテキスト)。
- これを <ClerkProvider> で囲むことで、すべてのページで useUser() や useAuth() などの Clerkの認証関連のフックが使える ようになる。
2️⃣ アプリ全体のレイアウトを定義
export default function RootLayout({
children,
}: {
children: React.ReactNode;
}) {
- RootLayout は 関数コンポーネント(Reactの基本的なコンポーネントの形)。
- export default を使っているので、他のファイルから import して使うことができる。
- React.ReactNode を型として指定することで、あらゆるReact要素が children に渡せるようになる。
- これにより、RootLayout の children に JSX要素、テキスト、数値、配列、フラグメントなどを安全に渡せる。
- RootLayout は アプリの共通レイアウト を定義するコンポーネント。
- children には、アプリ内のすべてのページのコンテンツ が入る。
たとえば、こんなイメージ👇
<RootLayout>
<HomePage /> // ホームページ
<SignInPage /> // サインインページ
</RootLayout>
3️⃣ ClerkProvider でアプリ全体を囲む
return (
<ClerkProvider>
<html lang="ja">
<body>{children}</body>
</html>
</ClerkProvider>
);
- <ClerkProvider> を使うことで、アプリの すべてのページでClerkの認証が有効 になる。
- children の中に、ページのコンテンツが動的に入る。(Next.js の layout.tsx でよく使われる仕組み)
- サインアップ・ログインページを作成
src/app/sign-in/page.tsx を作成し、以下のコードを追加します。
import { SignIn } from "@clerk/nextjs";
export default function SignInPage() {
return <SignIn />;
}
同じように、src/app/sign-up/page.tsx も作成し、以下のコードを追加。
import { SignUp } from "@clerk/nextjs";
export default function SignUpPage() {
return <SignUp />;
}
- サインイン・サインアップボタンを設置
src/app/page.tsx(トップページ)に以下のコードを追加し、サインイン/サインアウトを管理するボタンを追加します。
import { SignInButton, SignOutButton, SignedIn, SignedOut } from "@clerk/nextjs";
export default function Home() {
return (
<main className="flex flex-col items-center justify-center min-h-screen">
<h1 className="text-2xl font-bold mb-4">OriginalSNS</h1>
<SignedOut>
<SignInButton />
</SignedOut>
<SignedIn>
<p>ログイン済み</p>
<SignOutButton />
</SignedIn>
</main>
);
}
- ClerkのMiddlewareを設定
src/middleware.ts を作成し、以下のコードを追加。
import { clerkMiddleware } from "@clerk/nextjs/server";
export default clerkMiddleware();
export const config = {
matcher: ["/((?!_next|.*\\..*).*)"],
};
Middleware(ミドルウェア)とは?(クリックで展開)
Next.js の Middleware(ミドルウェア) は、リクエストがサーバーに届く前に処理を挟むことができる仕組みです。Clerk の clerkMiddleware を使うことで、 ページが読み込まれる前に認証処理を実行 できます。つまり、middleware.ts は以下のことをしています:
- ユーザーがアクセスするたびに、認証を確認
- 認証済みならページをそのまま表示
- 未認証なら、ログインを求める(sign-in へリダイレクトなど)
clerkMiddleware() は Clerkの認証チェックを行う関数 です。
これにより、すべてのリクエストで ユーザーがログインしているかを自動でチェック できます。
matcher は、Middleware が適用されるルート(ページ)を指定する設定。
“/((?!_next|.*\\..*).*)” という正規表現は Next.js のシステムファイルや静的ファイルを除外し、通常のページのみに適用 する設定です。
この設定により
- ✅ /(トップページ)
- ✅ /dashboard(例)
- ✅ /profile(例)
- ❌ _next/static/…(Next.jsの内部ファイル)
- ❌ favicon.ico(アイコンなどの静的ファイル)
など、通常のページに対して 認証が適用 されます。
- 動作確認
ターミナルから開発サーバーを再起動して、動作を確認します。
npm run dev
ブラウザで http://localhost:3000/sign-in にアクセスし、Clerkのログインフォームが表示されれば成功です!
Clerkの認証ができたら、次は Supabaseをセットアップして、投稿をデータベースに保存する機能 を実装していきます!
コメント