技術棧:兩週能上線的組合
第 1 課你驗證了題目、找到第一批願意付錢的人。現在問題來了:要用什麼做?
工程師在這裡最容易踩的雷不是選錯框架,是選太久。比較 Next.js 和 Nuxt、比較 Supabase 和 PlanetScale、比較 Vercel 和 AWS,比到第三週競爭者已經上線收款了,你還在做評比試算表。技術選型不是考試,沒有最優解,只有夠好又快的解。
這堂課的立場很明確:我推薦一套組合,說清楚每一層的理由與限制,帶你從零初始化到骨架部署上線。你之後當然可以換,但先把第一個版本做出來。
這堂學什麼
- 推薦棧 Next.js 16 + Supabase + Vercel + Claude API 的選擇理由與每一層的職責
- 各層免費額度地圖:起步近乎零成本的邊界在哪
- 用 AI 加速開發的工作流:從需求描述到可跑程式碼的正確節奏
- 手把手:建立專案、設定環境變數、連上 Supabase、部署到 Vercel 拿到正式網址
- 常見坑與具體錯誤訊息:你大概率會踩到的四個地雷,先知道比較不慌
觀念一:為什麼是這四個

圖:Supabase 官網(2026 年 7 月實況),來源:supabase.com
Next.js 16:前後端住同一個專案
Next.js 16 是 2026 年前端的共識選項。App Router 現在已穩定且是預設;Turbopack 從 16 版起成為預設打包器,next dev 冷啟動明顯變快,Fast Refresh 也有感加速——這讓「改一行、驗一下」的迭代迴圈更順暢,和 Vibe Coding 的工作方式天然配合。
最關鍵的是:它把前端(React UI)和後端(API Route、Server Action)放在同一個專案裡。對小團隊和獨立開發者來說,這本身就是競爭優勢——不用維護兩個 repo、不用協調版本,Claude Code 幫你改一個功能時,上下文全在同一個地方,生出的程式碼更準確。
為什麼不是 Nuxt 或 SvelteKit? 都是好選擇。但 Next.js 有最大量的中文社群範例,也是 Claude Code 見過最多次的框架,AI 輔助品質最好。工具要選 AI 幫得上忙的。
Supabase:資料庫 + 認證 + 儲存,一個服務搞定
Supabase 的核心是「把 PostgreSQL 包成 SaaS」——你不用自己架資料庫、不用寫 Auth 系統,它幫你托管好,只要寫跟資料有關的邏輯就好。
2026 年 7 月現況,免費方案包含:500 MB 資料庫、1 GB 檔案儲存、5 GB 流量、每月 5 萬個活躍用戶、50 萬次 Edge Function 呼叫、最多同時跑 2 個專案。起步完全夠用。Pro 方案每月 $25 美元,等第 3 課設好金流、真的開始收款後再評估要不要升。
重要限制:免費方案的專案如果連續 7 天沒有 API 請求,會自動暫停。資料保留,但服務離線直到你手動恢復。開發期間不是問題,要跑 MVP 給早期用戶測試時要注意——常見坑第 1 條就是它。
Vercel:零設定部署 Next.js
Vercel 是 Next.js 的親爹。部署 Next.js 到 Vercel 幾乎零設定:它自動偵測框架、執行建置、配好 HTTPS 憑證,你只管 git push。每次 push 到主分支就自動重新部署;push 到其他分支會給一個 Preview 網址讓你先看效果,正式站完全不動。
2026 年現況:Hobby 方案免費,限個人非商業用途。等你真的在收款了,要升 Pro(每人每月 $20 美元,含 $20 使用額度)。MVP 和 Beta 測試期間放 Hobby 完全沒問題,第 5 課上線時我會再提醒你確認這個轉換時間點。
Claude API:你產品的 AI 能力層
Claude API 是你 AI 功能的引擎。主力款 Claude Sonnet 4.6 定價每百萬輸入 token $3、輸出 $15;要更省的話 Claude Haiku 4.5 只要 $1/$5,適合量大又簡單的呼叫;要最強推理再用 Claude Opus 4.8($5/$25)。多數 SaaS 的 AI 功能用 Sonnet 4.6 就很夠,之後再依成本微調。
這堂課先記一個概念:API 是邊際成本,沒有用就沒有費用。這是 AI SaaS 和傳統 SaaS 在成本結構上最大的差異——你的成本和用量正相關,定價策略必須反映這點。第 4 課會完整算 token 成本,設計不被吃掉利潤的方案。
觀念二:AI 加速開發的正確節奏
用 AI 寫程式快 3 倍的人和只快 20% 的人,差別不在會不會下 prompt,在有沒有結構化的工作節奏。

AI SaaS 開發的日常節奏長這樣:
- 你定義 what:這個功能做什麼、操作哪些欄位、什麼情況觸發、錯誤怎麼處理。用一段話說清楚。
- Claude Code 寫 how:給它看你的專案結構和這段需求描述,讓它動手。
- 你審查+測試:功能對不對、有沒有安全漏洞、錯誤有沒有處理到。
- 重複:下一個功能。
在這個節奏裡,你的時間花在「定義問題」和「驗收品質」,不是手打模板程式碼。這也是為什麼第 1 課要你先把題目驗證清楚——你對問題理解得夠深,Claude Code 才能生出方向對的程式碼。
關鍵習慣:每個新功能開始時,先給一段系統脈絡,讓 Claude Code 說計畫、你確認方向,再動手寫程式。範例:
目前技術棧:Next.js 16 App Router + TypeScript + Supabase + Tailwind CSS。
資料庫主要 table:users、subscriptions、ai_jobs。
要實作的功能:使用者登入後,可以輸入一段文字,送去 Claude API 做摘要,
摘要結果存回資料庫並顯示在頁面上。
請先說你的實作計畫(不要先寫程式碼),確認方向對了再動手。
讓它先說計畫、你確認,再寫程式——避免一路跑偏後大改。這個習慣從這堂課建立,以後每個功能都這樣做。
手把手實戰
目標:從空白到骨架部署上線。完成後你有一個跑得起來的 Next.js 16 專案、接上 Supabase 讀到真實資料、部署在 Vercel 拿到正式 HTTPS 網址,整條路線確認通了。
初始化 Next.js 16 專案
開終端機,執行:
npx create-next-app@latest my-saas --typescript --tailwind --eslint --app --src-dir --import-alias "@/*"
cd my-saas
參數說明:--typescript 加上型別保護(和 Supabase SDK 搭配必要)、--tailwind 內建 Tailwind CSS、--app 使用 App Router(現在的標準)、--src-dir 把程式碼整理進 src/ 資料夾。
裝好後跑 npm run dev,瀏覽器打開 http://localhost:3000 看到 Next.js 預設頁就成功了。
立刻初始化 git、做第一次 commit:
git init
git add .
git commit -m "init: create-next-app"
從第一行程式碼就進 git,後悔藥才吃得到。接下來每個小功能完成就 commit 一次。
建立 Supabase 專案
到 supabase.com 免費註冊,點「New project」:
- Organization:第一次用會請你建組織,隨便填個名字
- Project name:用你的產品名,例如
my-saas - Database Password:點系統生成的強密碼,存進密碼管理器
- Region:選 Northeast Asia (Tokyo)——給台灣用戶延遲最低
建立需要 1~2 分鐘。建好後到 Project Settings → API,複製兩個值備用:
Project URL:長得像https://xxxxxxxxxxxx.supabase.coanon publickey:前端用的公鑰,可以公開給瀏覽器
另外還有一個 service_role key:這個絕對不能出現在前端程式碼,不能進 git。它有完整資料庫存取權限,只在 Server 端使用。
設定環境變數
在專案根目錄新增 .env.local(Next.js 只在本機讀這個,不會被 build 進去):
# .env.local — 本機秘密,不進 git
NEXT_PUBLIC_SUPABASE_URL=https://xxxxxxxxxxxx.supabase.co
NEXT_PUBLIC_SUPABASE_ANON_KEY=eyJhbGci...(你的 anon key)
SUPABASE_SERVICE_ROLE_KEY=eyJhbGci...(你的 service_role key,只在 Server 用)
ANTHROPIC_API_KEY=sk-ant-...(從 console.anthropic.com 拿到)
NEXT_PUBLIC_ 開頭的變數會曝光給瀏覽器,所以只放公鑰進去。沒有這個前綴的變數只有 Node.js Server 端讀得到。
確認 .gitignore 裡有 .env.local:
grep "env" .gitignore
如果沒看到,手動補一行:
echo ".env.local" >> .gitignore
安裝 SDK:
npm install @supabase/supabase-js @anthropic-ai/sdk
```</div>
<div class="step"><h4>寫 Hello World:從 Supabase 讀資料</h4>
先建立 Supabase client 的共用函式,路徑 `src/lib/supabase.ts`:
```typescript
import { createClient } from '@supabase/supabase-js'
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
const supabaseAnonKey = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY
if (!supabaseUrl) throw new Error('NEXT_PUBLIC_SUPABASE_URL is not set')
if (!supabaseAnonKey) throw new Error('NEXT_PUBLIC_SUPABASE_ANON_KEY is not set')
export const supabase = createClient(supabaseUrl, supabaseAnonKey)
然後去 Supabase 後台 → Table Editor → Create a new table,建一張測試用的 table:
- Name:
posts - Columns:
id(uuid, primary key, defaultgen_random_uuid())、title(text, not null)、created_at(timestamptz, defaultnow()) - Row Level Security:先關掉(toggle 設成 disabled),測試完第 3 課一起開
用 Table Editor 插入一筆假資料(title 隨便填)。
接著把 src/app/page.tsx 改成:
import { supabase } from '@/lib/supabase'
export default async function Home() {
const { data: posts, error } = await supabase
.from('posts')
.select('*')
.order('created_at', { ascending: false })
if (error) {
return <div className="p-8 text-red-600">Error: {error.message}</div>
}
return (
<main className="p-8">
<h1 className="text-2xl font-bold mb-4">Posts</h1>
<ul className="space-y-2">
{posts?.map((post) => (
<li key={post.id} className="p-4 border rounded-lg">
{post.title}
</li>
))}
</ul>
</main>
)
}
跑 npm run dev,瀏覽器看到你剛才插入的那筆資料出現在頁面上——前端到資料庫這條路通了。
推上 GitHub,部署到 Vercel
建一個 GitHub private repo(到 github.com 點右上角「+」→「New repository」,全留空不要勾任何初始化選項),然後:
git remote add origin https://github.com/你的帳號/my-saas.git
git branch -M main
git add .
git commit -m "feat: supabase hello world"
git push -u origin main
到 vercel.com 用 GitHub 帳號登入,點「Add New → Project」,找到 my-saas 按 Import。
部署前先填環境變數:展開「Environment Variables」,把 .env.local 裡的四個變數全部照填(名稱和值完全一樣),填完再按「Deploy」。
建置約 1~2 分鐘,完成後拿到 my-saas-xxxx.vercel.app 網址。用手機打開確認頁面正常、資料顯示出來——整條 GitHub → Vercel → Supabase 路線通了。
這就是你接下來兩週的工作基礎。

免費額度地圖
| 服務 | 免費額度重點 | 升級門檻 |
|---|---|---|
| Next.js | 開源免費,永久無上限 | 無 |
| Supabase Free | 500 MB DB / 5 萬 MAU / 5 GB 流量 / 2 個專案 | 超過任一項,或要避免自動暫停 → Pro $25/月 |
| Vercel Hobby | 無限部署 / 100 GB 流量 / 非商業用途 | 商業收款後升 Pro $20/人/月 |
| Claude API | 無月費,按用量計費 | 無門檻,用多少付多少 |
| GitHub | 私人 repo 免費 | 無 |
起步月花費:接近 $0。你唯一的變動成本是 Claude API 呼叫,開發期間自己測試跑幾百次大概幾十元台幣。等有付費用戶、有真實用量了,再來算第 4 課的成本結構。

台灣金流先知道
第 3 課的核心是登入與金流,這裡先提一個很多人踩到才知道的限制。

Stripe 目前不支援台灣商家直接申請帳號。 2026 年現況,Stripe 在台灣尚未開放直接以台灣個人或公司身分申請——要用 Stripe 必須先在美國或香港開公司,成本和複雜度大幅增加。如果你的市場是台灣,推薦直接走本地金流:
- 藍新金流(NewebPay):MPG 介面一次串接信用卡、ATM 轉帳、超商代碼,有 Sandbox 測試環境,申請需商業登記
- 綠界金流(ECPay):功能相近,官方提供技術文件和各語言 SDK,支援信用卡+超商+物流整合
兩者都支援電子發票開立,符合台灣稅務法規。第 3 課會帶你把其中一個串進 Next.js 的 API Route。
AI SaaS 定價設計快照
你的定價最終決定利潤空間,這裡先給 2026 年的全景快照。
趨勢清楚:純按人頭的 SaaS 在 AI 時代愈來愈難做。愈來愈多 SaaS 公司改採混合定價(固定基礎費+變動用量計費),以及信用點數(credits)機制,把 AI 的邊際成本轉嫁到用量上,而不是全吃進固定月費裡。

對你的 MVP 來說,最簡單的起步結構:
- 免費方案:功能受限,讓用戶進來試(呼應第 1 課的驗證策略)
- 付費方案:解鎖核心功能 + 每月 N 次 AI 呼叫 quota
- 超量計費:超過 quota 按次付費
這套結構對用戶來說可預期,對你來說保護了利潤。第 4 課會帶你計算每次 Claude API 呼叫的實際成本,反推出定價數字。
常見坑
坑 1:Supabase 專案自動暫停,API 回傳 503 或資料一片空白
症狀:本機跑得好好的,但你放幾天沒碰、或部署上去讓早期用戶測試時,頁面突然空白或報錯。打開 Supabase 後台看到橘色的「Project paused」警告。
原因:免費方案連續 7 天沒有 API 請求自動暫停。解法:到後台點「Restore project」,等 1~2 分鐘重新啟動即可,資料不會消失。如果要給用戶長期測試,兩個選項:①用 Vercel Cron 每 6 天打一次 ping endpoint 保持活躍;②直接升 Supabase Pro($25/月)就沒有這個限制。有付費用戶了再升很合理。
坑 2:Vercel 部署後頁面空白或報 TypeError: Cannot read properties of undefined
本機跑得好好的,但部署後 Vercel 的 Function Logs 噴這個錯。九成是忘記在 Vercel 後台填環境變數。
確認步驟:Vercel 專案 → Settings → Environment Variables,確認 NEXT_PUBLIC_SUPABASE_URL、NEXT_PUBLIC_SUPABASE_ANON_KEY、SUPABASE_SERVICE_ROLE_KEY、ANTHROPIC_API_KEY 全部都有填。填完後要點「Redeploy」——環境變數在 build 時注入,只 push 新程式碼是不夠的。
坑 3:Supabase RLS 開啟後 query 回傳 [] 空陣列,資料明明在
症狀:Table Editor 裡看得到資料,但程式 query 出來是空陣列,不是錯誤。
原因:Row Level Security 開啟後,所有 query 在沒有 policy 的情況下回空集合——這是設計行為,不是 bug。這堂課的 Hello World 步驟建議先關掉 RLS,第 3 課做認證時一起把 policy 設好。
如果你已經在其他情況下把 RLS 打開了:去 Supabase → Authentication → Policies,幫 posts table 新增一條 Policy:
-- 允許所有人讀取 posts(測試用,第 3 課會改成只有登入用戶)
CREATE POLICY "allow_public_read" ON posts
FOR SELECT USING (true);
坑 4:build 時 TypeScript 報 Type 'string | undefined' is not assignable to type 'string'
本機 npm run dev 不會報,但 npm run build(Vercel 部署時跑的)是嚴格模式,直接讓部署失敗。常見觸發點:
// ❌ 這樣會讓 build 炸掉
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL // 型別是 string | undefined
const client = createClient(supabaseUrl, ...) // 預期 string
解法:在 src/lib/supabase.ts 裡加環境變數檢查(如實戰第 4 步的寫法):
const supabaseUrl = process.env.NEXT_PUBLIC_SUPABASE_URL
if (!supabaseUrl) throw new Error('NEXT_PUBLIC_SUPABASE_URL is not set')
這樣 build 時如果變數沒設,錯誤訊息會直接告訴你哪個變數缺了,debug 快很多。判斷標準:本機跑 npm run build 能過,Vercel 幾乎就能過——所以每次 push 前先本機 build 一次。
作業
- 照今天的步驟把骨架建起來:Next.js 16 → 連上 Supabase → 能從資料庫讀到資料 → 部署 Vercel 拿到正式 HTTPS 網址,傳給一個朋友用手機打開
- 在 Supabase 建一張和你的產品相關的 table(不用完美,把主要欄位想清楚),插入幾筆假資料,用 Next.js 把它顯示出來
- 打開
.gitignore確認.env.local在裡面;打開 GitHub repo 確認檔案列表裡看不到任何.env或包含key、secret、password的檔案 - 選做:在
src/app/api/hello/route.ts寫一個 API Route,呼叫 Claude API 回傳一段文字,用瀏覽器打開/api/hello確認 key 能用:
// src/app/api/hello/route.ts
import Anthropic from '@anthropic-ai/sdk'
const client = new Anthropic({ apiKey: process.env.ANTHROPIC_API_KEY })
export async function GET() {
const message = await client.messages.create({
model: 'claude-sonnet-4-6',
max_tokens: 64,
messages: [{ role: 'user', content: '用一句話說你好' }],
})
const text = message.content[0].type === 'text' ? message.content[0].text : ''
return Response.json({ message: text })
}
下一課預告
骨架上線了,接下來要讓它變成一個真正的產品——有帳號系統、有收款能力。第 3 課「登入與金流:收得到錢才是產品」會帶你用 Supabase Auth 做 email + 社交登入,把 Row Level Security 的 policy 設好保護用戶資料,並串接台灣本地金流(藍新或綠界),讓第一個真實用戶付款。沒有收款能力的產品,只是個 demo。