実務・技術解説
Next.js + Supabase + Vercel でMVPを作る——構成・セットアップ・本番化の注意点
Vibe Codingツールが最もよく生成する技術構成「Next.js + Supabase + Vercel」の全体像を解説。なぜこの構成なのか、セットアップ手順、本番化で外せない確認事項まで。
Cursor・Bolt.new・Lovable・v0・Claude Codeで生成されるコードを見ると、圧倒的に多い構成が Next.js + Supabase + Vercel だ。
なぜこの3つが揃うかというと、AIがこの組み合わせを学習しているからだけではなく、実際にMVPを最速で立ち上げるのに向いている構成だからだ。
- Next.js:Reactベースのフルスタックフレームワーク。フロントエンドとAPIを一つのプロジェクトに書ける
- Supabase:PostgreSQLのデータベース、認証、ストレージがセットになったBaaS。フロントから直接叩ける
- Vercel:Next.jsの開発元が提供するホスティング。GitHubプッシュで自動デプロイ
3つとも無料枠で始められる。初期費用ゼロでフルスタックのWebアプリが動く環境が揃う。
構成図
ブラウザ
↓ HTTPS
Vercel(ホスティング)
└── Next.js
├── pages / app ルーター(UIの表示)
├── API Routes / Server Actions(サーバー処理)
└── Supabase SSRクライアント
↓ API通信
Supabase
├── PostgreSQL(データベース)
├── Auth(メール・Google・GitHub認証)
├── Storage(ファイル保存)
└── RLS(行レベルのアクセス制御)
重要な点:Supabaseはフロントエンドから直接APIを叩けるが、RLSが設定されていないとデータが全公開になる。この構成で最も注意が必要なのがRLSの設定だ。
セットアップ手順
Next.jsプロジェクトの作成
npx create-next-app@latest my-mvp --typescript --tailwind --app
cd my-mvp
--app は App Router(最新の記法)を使うオプション。Lovableやv0が生成するコードはApp Routerベースが多いので、合わせておくと移植しやすい。
Supabaseの設定
- supabase.com でプロジェクトを作成
- Project URL と anon key をコピー
.env.localに追加:
NEXT_PUBLIC_SUPABASE_URL=https://xxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGciOi...
- クライアントをインストール:
npm install @supabase/supabase-js @supabase/ssr
- クライアントを設定:
// utils/supabase/client.ts(ブラウザ用)
import { createBrowserClient } from '@supabase/ssr'
export function createClient() {
return createBrowserClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!
)
}
// utils/supabase/server.ts(サーバー用)
import { createServerClient } from '@supabase/ssr'
import { cookies } from 'next/headers'
export function createClient() {
const cookieStore = cookies()
return createServerClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{ cookies: { get: (name) => cookieStore.get(name)?.value } }
)
}
テーブルの作成とRLSの設定
-- 例:投稿テーブルの作成
CREATE TABLE posts (
id UUID DEFAULT gen_random_uuid() PRIMARY KEY,
user_id UUID REFERENCES auth.users(id) NOT NULL,
title TEXT NOT NULL,
content TEXT,
created_at TIMESTAMPTZ DEFAULT now()
);
-- RLSを必ず有効化する
ALTER TABLE posts ENABLE ROW LEVEL SECURITY;
-- ポリシー:自分の投稿だけ操作できる
CREATE POLICY "own_posts_select" ON posts
FOR SELECT USING (auth.uid() = user_id);
CREATE POLICY "own_posts_insert" ON posts
FOR INSERT WITH CHECK (auth.uid() = user_id);
CREATE POLICY "own_posts_update" ON posts
FOR UPDATE USING (auth.uid() = user_id);
CREATE POLICY "own_posts_delete" ON posts
FOR DELETE USING (auth.uid() = user_id);
テーブルを作るたびにRLSを設定する。忘れやすいが、忘れると全データが公開になる。
RLSの設定漏れが心配なら、Supabaseセキュリティ診断でアプリのURLを入れるだけでデータ露出リスクを自動チェックできる。
Vercelへのデプロイ
# GitHubにプッシュ
git init && git add -A && git commit -m "Initial commit"
# Vercel CLIでデプロイ(またはGitHub連携でダッシュボードから)
npx vercel
Vercelのダッシュボードから環境変数(SupabaseのURL・キー)を設定する。
本番化で外せない確認事項
開発用と本番用のSupabaseを分ける
Supabaseのプロジェクトを2つ作る:開発用と本番用。開発中に入れたテストデータが本番に混在すると問題になる。Vercelの環境変数で接続先を切り替える。
# 本番環境(vercel.com の環境変数設定)
NEXT_PUBLIC_SUPABASE_URL=本番のURL
NEXT_PUBLIC_SUPABASE_ANON_KEY=本番のkeyNEXT_PUBLIC_SUPABASE_ANON_KEY
# プレビュー環境
NEXT_PUBLIC_SUPABASE_URL=開発のURL
service role key を絶対にフロントに置かない
Supabaseには2種類のキーがある:
- anon key:フロントエンドで使うキー。RLSが適用される
- service role key:RLSをバイパスして全データにアクセスできる管理者キー
service role key が NEXT_PUBLIC_ で始まる環境変数に入っていると、全データが漏洩する。NEXT_PUBLIC_ を付けずに .env.local に保管し、API Routesからのみ使用する。
メール認証を有効にする
Supabase Authのデフォルト設定では、メール確認なしでアカウントが作れる。本番では「Email Confirmations」を有効にする。
Supabaseダッシュボード → Authentication → Providers → Email → 「Confirm email」をオンにする。
Supabaseの無料枠の限界を知っておく
| リソース | 無料枠 | Pro($25/月) |
|---|---|---|
| DB | 500MB | 8GB |
| バックアップ | なし | 毎日 |
| 同時接続 | 20 | 90〜 |
| Edge Functions | 50万回/月 | 200万回/月 |
バックアップがないのが最大のリスクだ。 ユーザーのデータが入っている状態でデータベースが壊れたとき、復元できない。100人以上のユーザーがいるならProプランへの移行を検討する。
よくある質問
この構成で作れないものは何ですか?
大規模なリアルタイム通信(チャット等)は、Supabase Realtimeで小規模なら対応できるが、数千人同時接続だと別の構成が必要になる。動画処理はCloudflare StreamなどのCDNが別途必要。それ以外の一般的なWebアプリはこの構成で対応できる。
v0で生成したUIをこの構成に組み込めますか?
できる。v0のコードはNext.js + Shadcn/uiベースなので、そのままApp Routerのプロジェクトに組み込める。Supabaseとのデータ接続は自分で追加する必要がある。
Lovableで作ったアプリもこの構成ですか?
LovableはNext.jsではなくReact + Viteを使うことが多い。Supabaseとの連携はあるため、Supabaseの部分は共通だがVercelへのデプロイ方法は少し異なる。Lovableからエクスポートした場合、デプロイ先はNetlifyが多い。
この構成でMVPを作ってRLSやインフラの設定で詰まった場合、または本番化の確認をしてほしい場合は、AIのあとしまつに相談してほしい。