はじめに
このリポジトリは、Next.js (App Router) と Supabase、Stripe、そして Resend を組み合わせることで、SaaSプロダクトの土台を手早く作成するためのスターターキットです。
ユーザー認証から定期課金、メール配信、データベースマイグレーションまで、あらかじめセットアップされているので、最低限の設定で本格的なサービスをスタートできます。
この記事では、実装されている機能の詳細やキッティング(環境構築)方法、さらに独自機能を追加していくときの流れについてお話しします。
主な機能
1. 認証機能 (Supabase)
-
Supabase Auth
メールアドレスやOAuth (GitHub・Googleなど) を使ったログイン/サインアップを標準サポート。 -
行レベルセキュリティ (RLS)
Supabaseの強力なRLS機能を利用し、自分のデータにだけアクセス可能など、柔軟なセキュリティポリシーを実装できます。
2. 課金・サブスク管理 (Stripe)
-
Stripe Checkout / サブスクリプション
月額や年額、あるいは一括払いなどを柔軟に設定可能。 -
Webhooks
Stripe上のプロダクト・価格変更などが発生したら、自動でSupabase上のデータを更新します。
3. メール送信 (Resend)
-
React Email
メールテンプレートをReactベースで管理でき、レスポンシブなメールが簡単に作成できます。 -
Resend API
環境変数にAPIキーを設定しておくと、resendClient.emails.send()
ですぐに送信可能。
4. UIコンポーネント (shadcn/ui + Tailwind CSS)
-
shadcn/ui
Radix UIをベースにした高品質・アクセシブルなUIが導入済み。 -
Tailwind CSS
ユーティリティクラスを使った開発スタイルで高速にコーディング。 -
セクシーなボーダーアニメーション
sexy-boarder.tsx
というユニークなコンポーネントで、要素周りにグラデーションアニメーションを付与できます。
5. DBマイグレーション (Supabase CLI)
-
supabase/migrations ディレクトリ
DDLスクリプトを追加してnpm run migration:up
を実行すれば、DBスキーマをバージョン管理できます。 -
seed.sql
初期データ投入(シード)が必要な場合に実行できる設定ファイルがあります。
6. ESLint / Prettier / Git管理
-
.eslintrc.json
シンプルな構成で、simple-import-sort
などの便利なプラグインもプリセット済み。 -
.prettier.config.js
Tailwindと衝突しないようにprettier-plugin-tailwindcss
を導入。 -
.gitignore
.env.local
など、秘匿情報が自動的にリポジトリに含まれないように管理。
ファイル構成ざっくり紹介
"src/" ディレクトリにはページや機能単位の処理がまとまっています。
"supabase/" ディレクトリはマイグレーション管理用のSQLが格納されています。
"public/" には画像・アイコン類が配置されています。
キッティング手順(環境構築の流れ)
1. Supabaseプロジェクトの準備
- supabase.com で新規プロジェクトを作成
-
.env.local
の環境変数を取得していく(.env.local.example
を参考)
a. NEXT_PUBLIC_SUPABASE_URL
- 「Settings」 → 「API」に移動。
- 「Project URL」セクションに記載されているURLをコピーして、
.env.local
のNEXT_PUBLIC_SUPABASE_URL=
に設定します。
b. NEXT_PUBLIC_SUPABASE_ANON_KEY
- 同じく「Settings」 → 「API」ページにある「API Keys」セクション内で、「anon key」を探します。
- このキーは公開キーで、フロントエンドからSupabaseに接続するために使用されます。
- コピーして、
.env.local
のNEXT_PUBLIC_SUPABASE_ANON_KEY=
に設定します。
c. SUPABASE_SERVICE_ROLE_KEY
- 「Settings」 → 「API」 → 「Service Role」セクションで取得可能です。
- このキーは高い権限を持つバックエンド専用キーであり、公開しないように注意してください。
-
.env.local
のSUPABASE_SERVICE_ROLE_KEY=
に設定します。
d. SUPABASE_DB_PASSWORD
- 「Settings」 → 「Database」 → 「Connection pooling」セクションにあるパスワードフィールド。
- プロジェクト作成時に設定したデータベースパスワードと同じです。
-
.env.local
のSUPABASE_DB_PASSWORD=
に設定します。
2. Stripeの準備
- stripe.com で新規プロジェクト作成
- Customer Portal Settingsでテスト用リンクを有効化
- APIキーを取得して .env.local へ設定
a. NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY
- StripeのAPIキー設定ページにアクセスして、公開可能なキー(Publishable key)を取得してください。
-
.env.local
に設定例:NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_XXXXXXXXXXXXXXXX
b. STRIPE_SECRET_KEY
- 同じAPIキー設定ページで、シークレットキー(Secret key)を取得してください。
-
.env.local
に設定例:STRIPE_SECRET_KEY=sk_test_XXXXXXXXXXXXXXXX
c. STRIPE_WEBHOOK_SECRET
- StripeのWebhook設定ページで、エンドポイントを作成します。
-
手順:
-
Developers > Webhooks
を選択。 -
Add endpoint
をクリックし、エンドポイントURLに<あなたのアプリのURL>/api/webhooks
を指定します。 - 必要なイベントを選択(例:
Select all events
)。 - 作成後、Webhook Signing Secretをコピーします。
-
-
.env.local
に設定例:STRIPE_WEBHOOK_SECRET=whsec_XXXXXXXXXXXXXXXX
以上のキーを取得して.env.local
に設定することで、Stripeの連携が正しく動作します。
開発環境でのSTRIPE_WEBHOOK_SECRET
の設定方法は以下の通りです。
手順
-
Stripe CLIのインストール
- Stripe CLIがインストールされていない場合は、以下のリンクを参照してインストールしてください。
Stripe CLI インストールガイド
- Stripe CLIがインストールされていない場合は、以下のリンクを参照してインストールしてください。
-
Stripe CLIでログイン
stripe login
-
Webhookリクエストをフォワード
- 次のコマンドで、ローカルのエンドポイントにリクエストをフォワードします。
stripe listen --forward-to http://localhost:3000/api/webhooks
- このコマンドを実行すると、Stripe CLIがWebhook Signing Secretを出力します。例:
> Ready! Your webhook signing secret is whsec_XXXXXXXXXXXXXXXX
- 次のコマンドで、ローカルのエンドポイントにリクエストをフォワードします。
-
Signing Secretを
.env.local
に設定- 出力された
whsec_XXXXXXXXXXXXXXXX
をコピーして、.env.local
に以下のように設定します:STRIPE_WEBHOOK_SECRET=whsec_XXXXXXXXXXXXXXXX
- 出力された
3. Resendの準備
- resend.com でアカウント作成
- APIキーを発行し、
.env.local
に書き込み
4. ローカル環境のセットアップ
- リポジトリを手元にクローンし、
npm i
-
.env.local
を作成し、.env.local.example
の内容をコピーして値を埋める -
npm run dev
でローカルサーバを起動し、http://localhost:3000 を確認
5. Stripe Webhookの設定
- Vercelなどにデプロイし、デプロイURLを取得
- Stripeダッシュボード → 「Developers」 → 「Webhooks」 → 「Add an endpoint」
- エンドポイントに
https://デプロイURL/api/webhooks
を登録 -
Select all events
を有効化 - 得られたWebhook SecretをVercelの環境変数や .env.local に
STRIPE_WEBHOOK_SECRET
として設定
6. Supabaseマイグレーション
npm run supabase:link
-
npm run migration:up
これでsupabase/migrations
ディレクトリ内にあるDDL (初期テーブル作成SQL) が適用されます。
7. Stripe Fixtureの適用
- Stripe CLI をインストール
-
stripe fixtures ./stripe-fixtures.json --api-key <YOUR_STRIPE_SECRET_KEY>
でテスト用Products/Pricesを作成 - SupabaseにもWebhookを経由して同期されます。
よく使うスクリプト
-
npm run dev
: Next.jsの開発サーバ起動 -
npm run build
: Next.jsの本番ビルド -
npm run supabase:link
: ローカルプロジェクトとSupabaseプロジェクトを紐付け -
npm run migration:new <migration_name>
: 新しいマイグレーションファイルを作成 -
npm run migration:up
: マイグレーションを実行 -
npm run email:dev
: React Emailの開発用プレビューサーバ起動
さらに細かい機能のポイント
-
ESLint + Prettier連携
-
simple-import-sort
プラグインでimport文が自動的に綺麗にソートされます。 - PrettierではTailwindのクラス順序を崩さないように
prettier-plugin-tailwindcss
を導入。
-
-
middleware.ts
による認証セッション管理- Next.jsのMiddlewareを活用し、
supabase-middleware-client
でサーバーサイドセッションを更新しています。 - 特定のルートをガードする実装もすぐに追加できます。
- Next.jsのMiddlewareを活用し、
-
アニメーション付きUI
-
tailwind.config.ts
で@keyframes spin-slow
を設定し、sexy-boarder.tsx
の背景をぐるぐる回転させられます。 - ボタンやドロップダウンなども、Radix UIをベースに各コンポーネントがしっかり作り込まれています。
-
-
複数のStripe Priceを切り替え可能
- 例えば「月額」「年額」のプランが存在する場合にタブ切り替えで表示金額を変えることができます。
-
pricing-section.tsx
やprice-card.tsx
を見ると、月額・年額をスイッチさせる仕組みがわかります。
-
メール送信の拡張
-
src/features/emails/
フォルダ配下にReact Emailのコンポーネントを追加するだけで、新しいメールテンプレートを作成可能。 - 送信は
resendClient.emails.send()
を呼び出すだけでOKです。
-
-
UIレイアウト (layout.tsx)
-
src/app/layout.tsx
でヘッダやフッタが構成されており、サイト全体の基本スタイルを管理。 -
<Analytics />
を利用するとVercel Analyticsが有効になります。
-
独自機能を開発する例
1. 新しいDBテーブルを追加 (例: Teams機能)
npm run migration:new add-teams-table
- 生成されたSQLファイルに
CREATE TABLE teams (...)
などのDDLを追記 -
npm run migration:up
でDBを更新
2. Stripe上のmetadataを拡張したい
-
stripe-fixtures.json
のmetadata
に独自キーを追加 (例:"max_team_members": 5
) -
src/features/pricing/models/product-metadata.ts
でZodスキーマにフィールドを追加 - Webhook経由で自動同期されるため、Supabaseにその項目が反映されます
3. メール送信フローを拡張
-
src/features/emails/フォルダ
に新しいReact Emailコンポーネントを作成 - 例えば「パスワードリセット」メールや「支払い失敗通知」メールなどを追加
- サーバーサイドの関数から
resendClient.emails.send()
で呼び出す
4. サブスクに応じてUIを変化させる
-
getSubscription()
やgetProducts()
でユーザーの現在のサブスク状態を取得 - 機能制限・ボタン有効化などのUIを分岐処理
まとめ
Next.js + Supabase + Stripe + Resend の組み合わせで、すぐにSaaSを立ち上げられるスターターキットです。
特長まとめ:
- エンドツーエンドで「ユーザー認証 → サブスク購入 → メール送信 → DB管理」をカバー
- shadcn/ui + Tailwindで開発が高速&スタイリッシュ
- StripeのフィクスチャやDBマイグレーション、Supabase CLIが整備されていて、運用もしやすい
一通り環境構築を終えたら、あとは機能拡張あるのみ。Teamsテーブルや通知メールなど、使いたい機能をどんどん追加していけば、自分だけのSaaSを自由にビルドできます。
ぜひ、プロジェクトのベースとして活用してみてください!