Template解説シリーズ②：Next.js + Supabase + Stripe で作る SaaS

## はじめに

このリポジトリは、**Next.js (App Router)** と **Supabase**、**Stripe**、そして **Resend** を組み合わせることで、SaaSプロダクトの土台を手早く作成するためのスターターキットです。

https://github.com/KolbySisk/next-supabase-stripe-starter/tree/main

ユーザー認証から定期課金、メール配信、データベースマイグレーションまで、あらかじめセットアップされているので、最低限の設定で本格的なサービスをスタートできます。

この記事では、実装されている機能の詳細やキッティング(環境構築)方法、さらに独自機能を追加していくときの流れについてお話しします。

---

## 主な機能

### 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` など、秘匿情報が自動的にリポジトリに含まれないように管理。

---

## ファイル構成ざっくり紹介

```mermaid
flowchart LR
    User["ユーザー"] --> Next["Next.js"]
    Next --> DB["Supabase"]
    Next --> Payment["Stripe"]
    Next --> Mail["Resend"]
    
    subgraph Database["データベース"]
        DB
    end
    
    subgraph PaymentSystem["決済"]
        Payment
    end
    
    subgraph EmailSystem["メール送信"]
        Mail
    end
```

> "src/" ディレクトリにはページや機能単位の処理がまとまっています。  
> "supabase/" ディレクトリはマイグレーション管理用のSQLが格納されています。  
> "public/" には画像・アイコン類が配置されています。

---

## キッティング手順（環境構築の流れ）

### 1. Supabaseプロジェクトの準備
1. [supabase.com](https://supabase.com) で新規プロジェクトを作成  
2. `.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の準備
1. [stripe.com](https://stripe.com) で新規プロジェクト作成  
2. [Customer Portal Settings](https://dashboard.stripe.com/test/settings/billing/portal)でテスト用リンクを有効化  
3. APIキーを取得して .env.local へ設定

#### a. **`NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY`**
   - Stripeの[APIキー設定ページ](https://dashboard.stripe.com/apikeys)にアクセスして、公開可能なキー（Publishable key）を取得してください。
   - `.env.local`に設定例:
     ```env
     NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_XXXXXXXXXXXXXXXX
     ```

#### b. **`STRIPE_SECRET_KEY`**
   - 同じAPIキー設定ページで、シークレットキー（Secret key）を取得してください。
   - `.env.local`に設定例:
     ```env
     STRIPE_SECRET_KEY=sk_test_XXXXXXXXXXXXXXXX
     ```

#### c. **`STRIPE_WEBHOOK_SECRET`**
   - Stripeの[Webhook設定ページ](https://dashboard.stripe.com/webhooks)で、エンドポイントを作成します。
   - **手順**:
     1. `Developers > Webhooks`を選択。
     2. `Add endpoint`をクリックし、エンドポイントURLに`<あなたのアプリのURL>/api/webhooks`を指定します。
     3. 必要なイベントを選択（例: `Select all events`）。
     4. 作成後、Webhook Signing Secretをコピーします。
   - `.env.local`に設定例:
     ```env
     STRIPE_WEBHOOK_SECRET=whsec_XXXXXXXXXXXXXXXX
     ```

以上のキーを取得して`.env.local`に設定することで、Stripeの連携が正しく動作します。

開発環境での`STRIPE_WEBHOOK_SECRET`の設定方法は以下の通りです。

#### 手順
1. **Stripe CLIのインストール**
   - Stripe CLIがインストールされていない場合は、以下のリンクを参照してインストールしてください。
     [Stripe CLI インストールガイド](https://stripe.com/docs/stripe-cli)

2. **Stripe CLIでログイン**
   ```bash
   stripe login
   ```

3. **Webhookリクエストをフォワード**
   - 次のコマンドで、ローカルのエンドポイントにリクエストをフォワードします。
     ```bash
     stripe listen --forward-to http://localhost:3000/api/webhooks
     ```
   - このコマンドを実行すると、Stripe CLIがWebhook Signing Secretを出力します。例:
     ```
     > Ready! Your webhook signing secret is whsec_XXXXXXXXXXXXXXXX
     ```

4. **Signing Secretを`.env.local`に設定**
   - 出力された`whsec_XXXXXXXXXXXXXXXX`をコピーして、`.env.local`に以下のように設定します:
     ```env
     STRIPE_WEBHOOK_SECRET=whsec_XXXXXXXXXXXXXXXX
     ```


### 3. Resendの準備
1. [resend.com](https://resend.com) でアカウント作成  
2. APIキーを発行し、`.env.local` に書き込み

### 4. ローカル環境のセットアップ
1. リポジトリを手元にクローンし、`npm i`  
2. `.env.local` を作成し、`.env.local.example` の内容をコピーして値を埋める  
3. `npm run dev` でローカルサーバを起動し、[http://localhost:3000](http://localhost:3000) を確認

### 5. Stripe Webhookの設定
1. Vercelなどにデプロイし、デプロイURLを取得  
2. Stripeダッシュボード → 「Developers」 → 「Webhooks」 → 「Add an endpoint」  
3. エンドポイントに `https://デプロイURL/api/webhooks` を登録  
4. `Select all events` を有効化  
5. 得られた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の適用
1. [Stripe CLI](https://stripe.com/docs/stripe-cli#install) をインストール  
2. `stripe fixtures ./stripe-fixtures.json --api-key <YOUR_STRIPE_SECRET_KEY>` でテスト用Products/Pricesを作成  
3. 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の開発用プレビューサーバ起動

---

## さらに細かい機能のポイント

1. **ESLint + Prettier連携**  
   - `simple-import-sort` プラグインでimport文が自動的に綺麗にソートされます。  
   - PrettierではTailwindのクラス順序を崩さないように `prettier-plugin-tailwindcss` を導入。

2. **`middleware.ts` による認証セッション管理**  
   - Next.jsのMiddlewareを活用し、`supabase-middleware-client` でサーバーサイドセッションを更新しています。  
   - 特定のルートをガードする実装もすぐに追加できます。

3. **アニメーション付きUI**  
   - `tailwind.config.ts` で `@keyframes spin-slow` を設定し、 `sexy-boarder.tsx` の背景をぐるぐる回転させられます。  
   - ボタンやドロップダウンなども、Radix UIをベースに各コンポーネントがしっかり作り込まれています。

4. **複数のStripe Priceを切り替え可能**  
   - 例えば「月額」「年額」のプランが存在する場合にタブ切り替えで表示金額を変えることができます。  
   - `pricing-section.tsx` や `price-card.tsx` を見ると、月額・年額をスイッチさせる仕組みがわかります。

5. **メール送信の拡張**  
   - `src/features/emails/` フォルダ配下にReact Emailのコンポーネントを追加するだけで、新しいメールテンプレートを作成可能。  
   - 送信は `resendClient.emails.send()` を呼び出すだけでOKです。

6. **UIレイアウト (layout.tsx)**  
   - `src/app/layout.tsx` でヘッダやフッタが構成されており、サイト全体の基本スタイルを管理。  
   - `<Analytics />` を利用するとVercel Analyticsが有効になります。

---

## 独自機能を開発する例

### 1. 新しいDBテーブルを追加 (例: Teams機能)
1. `npm run migration:new add-teams-table`  
2. 生成されたSQLファイルに `CREATE TABLE teams (...)` などのDDLを追記  
3. `npm run migration:up` でDBを更新

### 2. Stripe上のmetadataを拡張したい
1. `stripe-fixtures.json` の `metadata` に独自キーを追加 (例: `"max_team_members": 5`)  
2. `src/features/pricing/models/product-metadata.ts` でZodスキーマにフィールドを追加  
3. Webhook経由で自動同期されるため、Supabaseにその項目が反映されます

### 3. メール送信フローを拡張
1. `src/features/emails/フォルダ` に新しいReact Emailコンポーネントを作成  
2. 例えば「パスワードリセット」メールや「支払い失敗通知」メールなどを追加  
3. サーバーサイドの関数から `resendClient.emails.send()` で呼び出す

### 4. サブスクに応じてUIを変化させる
1. `getSubscription()` や `getProducts()` でユーザーの現在のサブスク状態を取得  
2. 機能制限・ボタン有効化などのUIを分岐処理  

---

## まとめ

**Next.js + Supabase + Stripe + Resend** の組み合わせで、すぐにSaaSを立ち上げられるスターターキットです。  

特長まとめ:  
- エンドツーエンドで「ユーザー認証 → サブスク購入 → メール送信 → DB管理」をカバー  
- shadcn/ui + Tailwindで開発が高速&スタイリッシュ  
- StripeのフィクスチャやDBマイグレーション、Supabase CLIが整備されていて、運用もしやすい

一通り環境構築を終えたら、あとは機能拡張あるのみ。Teamsテーブルや通知メールなど、使いたい機能をどんどん追加していけば、自分だけのSaaSを自由にビルドできます。
ぜひ、プロジェクトのベースとして活用してみてください！

---
### 会社紹介

**株式会社 Mosaica**  
最先端テクノロジーで社会課題を解決し、持続可能な未来を創造する IT カンパニー。
AI ソリューション、クラウド統合、DX 推進、経営コンサルティングなど包括的なサービスでビジネス変革を支援しています。  

詳しくは [公式サイト](https://mosaica.co.jp/) までお気軽にご相談ください。
公式サイト： https://mosaica.co.jp/