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

# はじめに

SaaS（Software as a Service）の開発には、ユーザー管理や決済システム、ダッシュボードなど、多岐にわたる機能を効率的に構築することが求められます。
その一方で、これらをゼロから作り上げるのは、初心者から上級者まで多大なコストと時間を要します。

そんな課題を解決するためにテンプレート「next-saas-starter」を見つけました。

https://github.com/leerob/next-saas-starter

このスターターテンプレートは、Next.jsやPostgres、Stripeといったモダンな技術スタックを活用し、SaaS開発に必要な基本機能をパッケージ化したものです。

本記事では、このテンプレート導入方法や主要な機能、さらには独自のカスタマイズ方法までを詳しく解説します。

## プロジェクト概要

`next-saas-starter` は、**Next.js**／**Postgres**／**Stripe** を活用して、素早くSaaSアプリケーションを構築するためのスターターテンプレートです。

ユーザー管理（JWT認証）や課金処理（Stripeサブスクリプション）、ダッシュボード（チーム・メンバー管理）など、SaaSでよく使われる機能が含まれています。

---

## 主な機能一覧

- **Authentication**  
  メールアドレス＆パスワード認証をJWTで管理。  
  - サインアップやサインインはクライアントコンポーネント化され、リアルタイムで入力バリデーションを実施  
  - 認証トークンはHTTPOnly Cookieに格納  
  - 「/sign-in」「/sign-up」ページを実装済み

- **Stripe決済**  
  月額制サブスクリプションをStripeで実現。  
  - Free／Base／Plusなどのプラン管理  
  - `/pricing` ページでプランを選び、Stripe Checkoutへ遷移  
  - Webhookで購読状況を更新し、チーム情報にサブスクリプションステータスを保存

- **ダッシュボード**  
  ログイン済みユーザー向けの管理画面。  
  - **Team管理**: チームの作成、招待リンク・メール送信、メンバー追加／削除など  
  - **セキュリティ設定**: パスワード更新やアカウント削除  
  - **アクティビティログ**: ユーザーごとの「サインイン」「パスワード更新」「メンバー招待」などの記録

- **Middleware**  
  Next.jsの`middleware.ts` を利用して認証チェックやリダイレクトを実装。  
  - `matcher: ['/((?!api|_next/static|_next/image|favicon.ico).*)']` で保護するルートを管理  
  - JWTの有効期限判定、クッキー削除、ログアウト時のハンドリング

---

## ディレクトリ構成

```bash
next-saas-starter/
├─ middleware.ts          # ルート保護のためのNext.js Middleware
├─ app/
│  ├─ (login)/
│  │  ├─ sign-up/
│  │  ├─ sign-in/
│  │  └─ login.tsx       # "Login" コンポーネント
│  ├─ (dashboard)/
│  │  ├─ dashboard/
│  │  ├─ pricing/
│  │  ├─ settings.tsx
│  │  ├─ security/
│  │  ├─ activity/
│  │  └─ invite-team.tsx
│  ├─ api/
│  │  └─ stripe/
│  │     ├─ checkout/
│  │     └─ webhook/
│  └─ layout.tsx
├─ lib/
│  ├─ auth/
│  ├─ payments/
│  ├─ db/
│  └─ utils.ts
├─ components/
│  ├─ ui/
│  └─ ...
└─ ...
```

- `app/(login)/...` : ログインやサインアップなどの未ログイン向けページ  
- `app/(dashboard)/...` : ダッシュボードや設定ページなどログイン後の画面  
- `lib/` : 認証ロジック／DB接続／Stripe決済などのビジネスロジック  
- `components/ui/` : shadcn/uiベースのUIコンポーネント集

---

## インストール＆セットアップ

1. **リポジトリのクローンとインストール**

   ```bash
   git clone https://github.com/leerob/next-saas-starter
   cd next-saas-starter
   pnpm install
   ```

2. **環境変数ファイルの生成**

   ```bash
   pnpm db:setup
   ```
   - `docker-compose.yml` の作成とローカルPostgres起動  
   - Stripe CLIを使ったWebhook設定  
   - `.env` ファイルに必要な各種キーを自動生成

3. **データベース初期化**

   ```bash
   pnpm db:migrate
   pnpm db:seed
   ```
   - `test@test.com / admin123` というユーザーとチームが登録される

4. **開発サーバ起動**

   ```bash
   pnpm dev
   ```
   - http://localhost:3000 にアクセス

---

## 各機能の詳しい流れ

ここでは、ユーザー登録（サインアップ）から有料プランに加入するまでの流れを例として説明します。

```mermaid
flowchart TB
    A[""ユーザーがサインアップページを表示""]
    B[""フォーム入力 → バリデーション""]
    C[""ユーザー＆チームをDB登録""]
    D[""セッションCookieを設定しダッシュボードにリダイレクト""]
    E[""有料プランを選択してStripe Checkoutへ遷移""]
    F[""Webhooksでサブスク状態をDB更新""]
    G[""ダッシュボードで新プランが反映""]
    
    A --> B
    B --> C
    C --> D
    D --> E
    E --> F
    F --> G
```

### 1. サインアップ〜ログイン
- `app/(login)/actions.ts` にある `signUp` / `signIn` サーバーアクションで、Zodによる入力検証とDB登録を実行  
- ユーザー登録が成功すると、Cookieにセッション情報（JWT）が格納され、ダッシュボードへ移行

### 2. Stripe決済
- `/pricing` ページでプラン選択後、Stripe Checkout APIを呼び出す (`checkoutAction`)  
- Checkout成功時に `/api/stripe/checkout` へリダイレクトし、サブスク情報をDB更新  
- `stripe listen --forward-to localhost:3000/api/stripe/webhook` のようにCLIを常時起動しておくと、本番同様のWebhook検証ができる

### 3. Middlewareでルートを保護
- `middleware.ts` で、`/dashboard` をはじめとする保護ルートへのアクセスをCookieによる認証チェック  
- 有効でなければ自動的に `/sign-in` にリダイレクト

### 4. ダッシュボード機能
- `/dashboard` → チームメンバー一覧やSubscription情報を表示  
- `/dashboard/general` → ユーザー名やEmail更新  
- `/dashboard/security` → パスワード変更やアカウント削除  
- `/dashboard/activity` → ログインやパスワード変更、チーム作成などの操作履歴  
- `/dashboard/invite-team` → メール招待し、チームメンバーとして追加

---

## 独自機能を追加するとき

1. **UIコンポーネントの追加**  
   - `components/ui/` 以下を参考に、shadcn/uiライクなスタイルを踏襲
2. **APIエンドポイント定義**  
   - `app/api/任意の名称/route.ts` でRESTful／RPCスタイル、どちらでも実装可能
3. **DBスキーマの変更**  
   - `lib/db/schema.ts` に列を追加し `drizzle-kit generate` / `migrate`  
4. **Middlewareや認証フックの拡張**  
   - ロールごと（`owner` / `member`）のアクセス制御を追加したい場合、`lib/auth/middleware.ts` で判定処理を付与

---

## 本番運用準備

1. **本番用StripeキーとWebhook**  
   - Stripeのダッシュボードで本番キー／Webhooksを設定し、`.env` に追加
2. **本番DB用URLを設定**  
3. **Vercelや任意のホスティングにデプロイ**  
   - `BASE_URL` や `AUTH_SECRET` を本番用に再設定  
   - GitHub連携で自動デプロイ（CI/CD）を構築

---

## まとめ

`next-saas-starter` を使うことで、以下のような利点が得られます。

- **サインアップ〜サブスク決済〜ダッシュボード管理** といったSaaSの基本フローが整備済み
- **Middleware** と **React Server Actions** により、認証やフォーム処理がシンプル
- **Shadcn/ui + Tailwind CSS** でUIカスタマイズが容易

特に、Stripe集金周りやチーム管理はSaaSアプリ構築の肝となる部分であり、ゼロから実装すると大きな手間がかかります。

本テンプレートを活用して開発初期コストを大幅に削減し、ビジネスロジックやUXに注力してみてください。

---
### 会社紹介

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

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