セットアップガイド
StartPack - 30分で始めるSaaS開発
# 概要
StartPackは、TypeScript + Next.jsをベースに、認証、決済、お問い合わせフォームが事前設定された完全なSaaS基盤を提供します。
主要機能
- ユーザー認証(Neon Auth または Supabase Authから選択)
- Stripeによるサブスクリプション決済
- Resendによるお問い合わせメール送信
- PostgreSQL(Neon / Supabase から選択、Prisma ORM使用)
- Tailwind CSS + shadcn/uiコンポーネント
ディレクトリ構造
startpack/
├── app/ # Next.js App Router
│ ├── api/ # APIルート
│ ├── auth/ # 認証ページ
│ ├── billing/ # サブスクリプション管理
│ ├── dashboard/ # ユーザーダッシュボード
│ ├── contact/ # お問い合わせフォーム
│ └── legal/ # 利用規約等
├── components/ # Reactコンポーネント
├── lib/ # ユーティリティ関数
├── prisma/ # データベーススキーマ
├── public/ # 静的ファイル
└── styles/ # グローバルスタイル# チュートリアル動画
StartPackの機能紹介から実際のセットアップ手順まで、動画でわかりやすく解説しています。
# クイックスタート
アプリケーションをローカル環境で起動する手順です。
# unzip
unzip startpack.zip
cd startpack
# 初期化(必ず先に実行)
npm run startpack:init
# プロンプトで番号を入力してプロバイダを選択します
# 1) Neon(Better Auth) / 2) Supabase Auth
# 選択したプロバイダ以外の依存とコードは自動で削除されます
# 依存をインストール(init の後)
npm install理由: 初期化スクリプトが package.json の依存関係やファイル構成をプロバイダに合わせて変更するため、先に初期化 → その後インストール の順にしてください。
共通準備
- 環境変数ファイルをコピー(どちらか一方を選択)
# Neon を使う場合 cp .env.neon.example .env # Supabase を使う場合 cp .env.supabase.example .env - .env を開き、下記「環境変数」を参考に必要項目を埋めます
3. Neonデータベースの接続情報を設定
- neon.tech でプロジェクトを作成(AWSリージョンはシンガポールがおすすめ)
- ダッシュボードの 「Connect to your database」 セクションを見つける
- 「Connect」 ボタンをクリック
- 表示された 「Connection string」 をコピー(パスワード含む)
.envのDATABASE_URLに貼り付け
DATABASE_URL="postgresql://user:password@ep-xxx.region.aws.neon.tech/neondb?sslmode=require"4. データベースを初期化
npm run db:migratePrisma CLI は .env を自動読み込みします。DATABASE_URL は .env に必ず設定してください。
5. 開発サーバーを起動
npm run dev認証、決済、メールなどを利用する場合は、下記の環境変数の .env をすべて埋めてから実行してください。
http://localhost:3002 でアプリケーションにアクセスできます
# 環境変数
プロバイダ別のテンプレートを切替表示できます。
# データベース(Neon)
DATABASE_URL=postgresql://user:password@host/database?sslmode=require
# 認証(Neon Auth / Better Auth)
NEXT_PUBLIC_NEON_AUTH_URL=https://ep-xxx.neonauth.region.aws.neon.tech/neondb/auth
# 退会機能(Neon API でユーザー削除)
# 設定しない場合、退会時に認証ユーザーは削除されません(手動削除が必要)
NEON_API_TOKEN=neon_api_key_...
NEON_PROJECT_ID=your-project-id
NEON_BRANCH_ID=br-xxx-xxx-123456
# 決済(Stripe)
STRIPE_SECRET_KEY=sk_test_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...
STRIPE_PRICE_ID=price_...
STRIPE_WEBHOOK_SECRET=whsec_...
# メール(Resend)
RESEND_API_KEY=re_...
CONTACT_EMAIL=you@example.com
# RESEND_FROM=support@yourdomain.com
# RESEND_DOMAIN=yourdomain.com
# レート制限(任意)
CONTACT_RATE_LIMIT_WINDOW_MS=60000
CONTACT_RATE_LIMIT_MAX=5# 認証設定
Neon Auth設定(Better Auth)
Neon AuthはNeonデータベースに統合された認証システムで、Better Authをベースにしています。認証データはneon_authスキーマに保存され、ブランチと一緒に管理されます。
セットアップ手順
- Neonダッシュボードで対象プロジェクトを開く
- 左メニューから Auth を選択
- Enable Neon Auth ボタンを押して有効化
- 表示される Auth URL をコピー
.envにNEXT_PUBLIC_NEON_AUTH_URLを設定
必要な環境変数
| 変数 | 説明 |
|---|---|
| NEXT_PUBLIC_NEON_AUTH_URL | Neon Auth URL(NeonダッシュボードのAuth設定からコピー) |
📖 詳細なセットアップ手順:Neon Auth ドキュメント
Neon Auth はプロジェクトごとに1構成
同一の Neon プロジェクト内に複数の Neon Auth 構成は設定できません。開発環境と本番環境で認証を分離したい場合は、 環境ごとに 別々の Neon プロジェクト を作成してください。
推奨手順
- Neon コンソールで 開発用プロジェクト(例: startpack-dev) を作成し、Auth を有効化。Auth URL を
.envに設定。 - 別途 本番用プロジェクト(例: startpack-prod) を作成し、同様に Auth を有効化。本番環境の環境変数に設定。
- 各環境で使用する
DATABASE_URLは、それぞれのプロジェクトの接続文字列を使用します。 - 認証データは
neon_authスキーマに保存され、環境ごとに独立します。
既に単一プロジェクトで運用している場合は、もう一つプロジェクトを新規作成し、Auth を有効化後にアプリ側の環境変数(NEXT_PUBLIC_NEON_AUTH_URL と DATABASE_URL)を切り替えてください。
💡 Neon Auth の特徴: 認証データがデータベースに直接保存されるため、ブランチを作成すると認証状態も一緒にコピーされます。これにより、テスト環境でも本番と同じ認証ワークフローを再現できます。
退会機能の設定(任意)
退会時に認証ユーザーも完全に削除するには、Neon API の認証情報を設定します。 未設定の場合、サブスクリプション等のアプリデータのみ削除され、認証ユーザーは neon_auth スキーマに残ります(Neonダッシュボードから手動削除可能)。
| 変数 | 説明 |
|---|---|
| NEON_API_TOKEN | Neon Personal API Key |
| NEON_PROJECT_ID | NeonプロジェクトID |
| NEON_BRANCH_ID | ブランチID(例: br-xxx-xxx-123456) |
取得方法
- NEON_PROJECT_ID: Neon Console → Settings → Project ID をコピー
- NEON_BRANCH_ID: Neon Console → Branches に表示される ID をコピー(例:
br-xxx-xxx-123456) - NEON_API_TOKEN: 右上のアカウントアイコン → Account settings → Personal API keys → Create new API key で作成
# 決済連携
Stripe設定
開発環境でのテスト: Stripe は必ず テストモード(サンドボックス) を使用してください。 APIキー、商品/価格、Webhook いずれも テストモード で取得・作成したものを使います。
- キーの接頭辞:
sk_test_/pk_test_ - Price ID はテストモードで作成したもの(例:
price_...) - Webhook シークレットもテストモード側で取得
1. APIキー
- Stripeダッシュボードにログイン
- (開発環境)右上の テストモード(サンドボックス)をON
- 開発者 → APIキー に移動
- 公開可能キー(
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY)とシークレットキー(STRIPE_SECRET_KEY)の両方をコピー
.env に設定:
STRIPE_SECRET_KEY=sk_test_...
NEXT_PUBLIC_STRIPE_PUBLISHABLE_KEY=pk_test_...2. サブスクリプション商品の作成
開発環境では テストモード 側で商品/価格を作成してください(本番とは別管理です)。
- 商品 → 商品を追加 に移動
- 商品名と価格を設定
- 課金タイプは「継続」、請求周期は「毎月」を選択
- Price ID(形式:
price_xxx)をコピー
.env に設定:
STRIPE_PRICE_ID=price_...3. Webhook設定
エンドポイントURL:
https://yourdomain.com/api/stripe/webhook必要なイベント(StartPackのサブスク実装):
checkout.session.completed(初回決済完了 → サブスクリプション保存)customer.subscription.updated(キャンセル予約・期間更新 等の反映)customer.subscription.deleted(サブスクリプション終了)invoice.payment_succeeded(月額課金の成功を反映)invoice.payment_failed(課金失敗を反映)
なお、必要に応じて受信するWebhookイベントや処理内容は調整してください(例: トライアル開始/終了、支払い要承認など)。
Stripe CLIでのローカル開発
インストール手順はStripe CLI公式ドキュメントを参照してください。
事前に Stripe ダッシュボードへ テスト(サンドボックス)環境でログインしてから、下記の stripe login を実行してください(ブラウザが開いて認証されます)。
# ログイン
stripe login
# webhookをlocalhostに転送
stripe listen --forward-to localhost:3002/api/stripe/webhook
# 表示されたwebhookシークレットをコピー.env に設定:
STRIPE_WEBHOOK_SECRET=whsec_...テストカード:Stripeテストカード一覧
# カスタマーポータル
Stripeのカスタマーポータルを有効化して、ユーザーが自分で支払い方法や請求履歴、キャンセル/再開を管理できるようにします。
Stripeダッシュボードで有効化
- Stripeダッシュボード → 設定 → Billing → カスタマーポータル
- カスタマーポータルのリンクを有効にする をオン
# メール設定
Resendセットアップ
- resend.com でサインアップ
- ダッシュボードでAPIキーを作成
RESEND_API_KEYに追加- お問い合わせフォームの受信用に
CONTACT_EMAILを設定
ドメイン検証(本番環境)
- Resendダッシュボードでドメインを追加
- DNSレコードを設定(SPF、DKIM)
- ドメイン所有権を確認
- .envの
RESEND_DOMAINを更新
⚠️ 開発環境の制限: ドメイン検証なしでは、アカウント所有者のメールアドレスにのみメールを送信できます。
さらに、未検証ドメインでは送信元は onboarding@resend.dev のみ許可されます(noreply@resend.dev などは不可)。
ローカルでは CONTACT_EMAIL を Resend アカウントのメール(または許可された受信先)に設定してください。
Neon Auth(Better Auth)の認証メール:
Neon Auth の認証メールはシステムで自動管理されます。カスタマイズが必要な場合は、Neon ダッシュボードの Auth 設定を確認してください。
# お問い合わせフォームのレートリミット
お問い合わせフォームには、スパム防止のためのレートリミット機能が搭載されています。 同一IPアドレスから短時間に大量のリクエストが送信された場合、一時的にアクセスを制限します。
デフォルト設定
- 制限時間: 60秒間
- 最大送信回数: 5回
- 制限対象: IPアドレス単位
つまり、同じIPアドレスから60秒間に6回目以降のお問い合わせは一時的に拒否されます。
設定のカスタマイズ
環境変数で制限を調整できます:
CONTACT_RATE_LIMIT_WINDOW_MS: 制限時間(ミリ秒)。デフォルト60000(60秒)CONTACT_RATE_LIMIT_MAX: 最大送信回数。デフォルト5
制限時の表示: 制限に達すると「リクエストが多すぎます。しばらく時間をおいて再度お試しください。」というメッセージが表示されます。
# お問い合わせメールのカスタマイズ
お問い合わせフォームのメール送信は /app/api/contact/route.ts で実装されています。 テキスト形式のメールで、件名・本文・送信元を自由にカスタマイズできます。
現在の設定
- メール形式: テキスト形式
- 送信元:
Contact Form <onboarding@resend.dev> - 送信先:
CONTACT_EMAIL環境変数 - 返信先: ユーザーが入力したメールアドレス
- 件名:
[お問い合わせ] ○○様からのお問い合わせ
カスタマイズ例
コード内の以下の部分を編集してください:
1. 件名の変更
subject: `【サービス名】お問い合わせ from ${safeName}`2. 送信元の変更(ドメイン検証後)
from: `サポート <support@yourdomain.com>`3. 本文テンプレートの変更
text: `お問い合わせありがとうございます
お名前: ${safeName}
メールアドレス: ${safeEmail}
お問い合わせ内容:
${safeMessage}
---
このメールは自動送信されています。
サポートチーム`開発環境での注意: Resend でドメイン未検証の場合、送信元は onboarding@resend.dev のみ使用可能です。CONTACT_EMAIL をResendアカウントのメールに設定してください。
# トラブルシューティング
データベース接続に失敗する
一般的な原因:
- .env に
DATABASE_URLが未設定 / タイプミス - DATABASE_URLフォーマットが正しくない
?sslmode=requireパラメータがない- データベースが初期化されていない
解決方法:
# Prismaクライアントを生成(初回/スキーマ変更時)
npm run db:generate
# データベースをリセット
npm run db:migrate
# 注意: Prismaは .env を読み込みます(.env.local のみではNG)
# 重要: npx prisma ではなく npm run db:* を使用してください(Prisma 7互換性問題を回避)認証が機能しない
確認事項:
- Neon Auth が有効で、Auth URL を取得済み
NEXT_PUBLIC_NEON_AUTH_URLが設定されている- ブラウザでCookieが有効になっている
- APIルート
/api/auth/[...all]/route.tsが存在している
Stripe決済が失敗する
確認事項:
STRIPE_PRICE_IDが「継続・毎月」のPriceに対応している- 公開可能キー/シークレットキーのモード(テスト/本番)が一致
- Webhookエンドポイントが正しく設定され、必要イベントが選択されている
STRIPE_WEBHOOK_SECRETが正しい(Invalid signature は取り違えのサイン)- ローカル:
stripe listen実行中(転送先: localhost:3002)
メールが送信されない
開発環境:
CONTACT_EMAILをResendアカウントのメールに設定RESEND_API_KEYが設定されている- Resendダッシュボードでログを確認
本番環境:
- ドメイン検証を完了
- SPF/DKIMレコードを確認
RESEND_FROMを本番ドメインの送信元に設定
ビルドエラー
# キャッシュをクリアして再インストール
rm -rf node_modules .next
npm install
npm run build