精華筆記

· @aihub.tw

Vibe Coding 建站實戰

綜合實戰:做一個作品集網站+聯絡表單,完整走一遍

綜合實戰:做一個作品集網站+聯絡表單,完整走一遍

前面 7 課,你學了一堆單項技能:會用 Lovable、會開 Claude Code、會 push 會部署、會寫 CLAUDE.md、知道資安坑在哪。但單項技能有個殘酷的真相:分開都會,不代表串起來會。就像學開車,倒車入庫、路邊停車分開練都過了,真正上路是另一回事——因為上路時沒有人告訴你「現在該用哪一招」。

這堂課就是上路考。我們從零開始做一個真的用得上的東西:你自己的作品集網站,含一個真的收得到信的聯絡表單,從需求、建站、表單、資安檢查、部署到綁網域,一站不跳。做完這堂課,你手上會有一個能放進履歷、印上名片的正式網址,以及更重要的——一套以後做任何網站都能重複套用的完整流程。

這堂課適合誰 適合:上完前 7 課、想把所有技能串成一次完整實戰的人(本課程屬進階應用專區)。需要基礎:零程式基礎 OK,但要會用電腦、會開終端機。前置課:第 3 課(Claude Code 環境)、第 4 課(GitHub + Vercel 帳號)是硬前置;第 5、7 課的 prompt 技巧會在這堂課大量回收使用。

這堂學什麼

  • 動手前先寫「一頁需求文件」:把腦中的模糊想法變成 AI 不會誤解的規格
  • 用 Claude Code 從零建出作品集網站,並在第一天就把 CLAUDE.md 和 git 建好
  • 免後端聯絡表單:用 Formspree 讓靜態網站也能收信,搞懂它背後的原理
  • 上線前跑一次第 7 課的資安檢查 prompt,養成「部署前必掃」的習慣
  • GitHub → Vercel → 自訂網域,完整部署一遍(這次不看第 4 課筆記)
  • 全課程 10 大常見坑總整理 + 學完之後的下一步學習地圖

觀念:整條生產線,一張圖看完

先把這堂課要走的路攤開。你會發現每一站都是前面某一課教過的,今天只是第一次連著走:

從需求到上線六站生產線,每一站對應前面課程

需求(第 5 課的描述術)→ 建站(第 3 課的 Claude Code)→ 表單(今天的新料)→ 資安檢查(第 6、7 課)→ 部署(第 4 課)→ 網域(第 4 課)。唯一的新東西是聯絡表單,所以先講清楚它的原理。

觀念:沒有後端,表單怎麼收信?

作品集網站是靜態網站:只有畫面,沒有伺服器幫你處理資料。那訪客按下「送出」之後,那封信要去哪?自己寫後端來收,你就要管伺服器、管資料庫、管垃圾信——為了一個月可能只有幾封的來信,完全不划算。

解法是託管表單服務:表單畫面還是在你的網站上,但「送出」的目的地指向別人家的伺服器,由它幫你收下資料、轉寄到你的信箱、順便擋垃圾信。

Formspree 免後端表單原理:訪客送出到 Formspree,轉寄進你的信箱

這類服務裡最老牌的是 Formspree(2026 年 7 月現況:免費方案每表單每月 50 則、表單數量不限、保留 30 天紀錄,對作品集綽綽有餘;不夠用再升 Personal 方案每月 15 美元)。類似的還有 Web3Forms、Basin,原理全部一樣,今天用 Formspree 示範,學會一個等於全會。

它的整合簡單到不可思議:你只需要把表單的 action 指到 Formspree 給你的專屬網址。你的網站從頭到尾不需要寫一行後端程式,也不需要保管任何金鑰——這也是為什麼它對新手特別安全,沒有金鑰就沒有金鑰外洩的問題。

手把手實戰

寫一頁需求文件(動手前最重要的 20 分鐘)

第 5 課說過:AI 做歪,九成是需求講太糊。這次我們在開專案之前,先把需求寫成一頁文件。照這個格式填:

一頁需求文件範例:目標、區塊、風格、驗收條件四大欄

四個欄位缺一不可:目標(這個網站給誰看、看完希望他做什麼)、區塊(頁面由上到下有哪些段落)、風格(給 2~3 個形容詞加一個參考網站)、驗收條件(完成的定義,例如「手機直向瀏覽不跑版」)。把它存成 REQUIREMENTS.md,等一下直接餵給 Claude Code。花 20 分鐘寫這張,後面至少省兩小時的來回修改。

用 Claude Code 建出網站骨架

開一個新資料夾(例如 my-portfolio),把 REQUIREMENTS.md 放進去,在裡面啟動 Claude Code,然後:

請讀 REQUIREMENTS.md,用 Vite + 原生 HTML/CSS/JS 幫我做這個作品集網站(不要用框架,保持簡單)。
規則:
1. 先列出你的檔案結構規劃給我看,我確認後才動工。
2. 作品區先用 3 個佔位作品卡,文字用假資料,我之後自己換。
3. 聯絡表單先做畫面就好(姓名、Email、訊息三個欄位),送出功能下一步才接。
4. 做完幫我跑起來,告訴我用哪個網址預覽。

逐段解釋:指定 Vite + 原生三件套是因為作品集不需要 React 的複雜度,愈簡單的專案 AI 愈不容易做錯;「先列規劃再動工」是第 5 課的鐵律;表單「先畫面後功能」是刻意把工作切小——一次只改一件事。

網站跑起來、瀏覽器確認長得像樣之後,立刻建立兩個保命裝置:

1. 幫我 git init、加上 .gitignore(要含 node_modules 和 .env),commit 這個初始版本。
2. 幫我建一個 CLAUDE.md,寫入:本專案用原生 HTML/CSS/JS 不引入框架;設計風格見 REQUIREMENTS.md;每次改動前先說明計畫。

從現在起,每完成一小步就 commit 一次。改壞了,git restore . 一秒回到上一個存檔點。

換上真實內容

把佔位假資料換成你自己的:自我介紹、真實作品(沒有正式作品就放課程做過的東西:第 2 課的 Lovable 網站、第 3 課的個人品牌網站,都是作品)、社群連結。一樣用 prompt 代打:

把作品區第一張卡換成:標題「AI 個人品牌網站」、描述「用 Claude Code 從零打造,含深色模式與 RWD」、連結 https://xxx.vercel.app。只改這張卡,其他不要動。

注意最後那句「只改這張卡,其他不要動」——第 5 課教的畫紅線,避免 AI 順手「幫」你重排整個版面。每換完一個區塊,瀏覽器看一眼、commit 一次。

註冊 Formspree,拿到表單網址

formspree.io 用 email 註冊免費帳號(記得去信箱點驗證信,沒驗證的帳號收不到轉寄)。登入後點「+ New form」,取名 portfolio-contact,建立後你會拿到一個表單專屬網址(endpoint),長這樣:

https://formspree.io/f/mabcdxyz

f/ 後面那 8 碼是你的表單 ID。這個網址不是秘密——它本來就會出現在網頁原始碼裡,被看到也沒關係,Formspree 靠自己那端的垃圾信過濾和額度控管來防濫用。所以它不用進 .env,這是它跟 API 金鑰本質上的不同。

把表單接上 Formspree

回到 Claude Code:

把聯絡表單接上 Formspree,我的 endpoint 是 https://formspree.io/f/mabcdxyz。
要求:
1. 用 fetch 以 AJAX 送出,不要跳轉頁面。
2. 送出成功後,表單原地顯示「訊息已送出,我會盡快回覆!」;失敗顯示「送出失敗,請稍後再試」。
3. 三個欄位都要有 name 屬性和 required 驗證。

它產出的核心程式碼會長這樣(逐段看懂,以後自己就能改):

<form id="contact-form" action="https://formspree.io/f/mabcdxyz" method="POST">
  <input type="text" name="name" placeholder="你的名字" required>
  <input type="email" name="email" placeholder="你的 Email" required>
  <textarea name="message" placeholder="想說的話" required></textarea>
  <button type="submit">送出</button>
</form>
const form = document.getElementById('contact-form');
form.addEventListener('submit', async (e) => {
  e.preventDefault(); // 攔下瀏覽器預設的跳轉行為
  const res = await fetch(form.action, {
    method: 'POST',
    body: new FormData(form),           // 把三個欄位打包
    headers: { Accept: 'application/json' }, // 告訴 Formspree:回我 JSON,不要回轉址頁
  });
  form.innerHTML = res.ok
    ? '<p>訊息已送出,我會盡快回覆!</p>'
    : '<p>送出失敗,請稍後再試。</p>';
});

三個重點:每個欄位的 name 屬性就是你收到信時的欄位名,沒寫 name 的欄位會整個消失(常見坑第 6 條);Accept: application/json 是讓 Formspree 用 JSON 回應而不是把使用者轉走;res.ok 為 true 代表 HTTP 狀態碼 2xx,送出成功。

接好之後立刻實測:在本機預覽頁填一筆假資料送出,回 Formspree 後台的 Submissions 頁看有沒有進來、你的信箱有沒有收到轉寄。測過才算完成,commit。

上線前資安掃描(第 7 課的肌肉記憶)

雖然這個專案沒有後端、沒有金鑰,風險本來就低,但「部署前必掃一次」的習慣要從第一個專案就養成。把第 7 課的檢查 prompt 拿出來用:

這個專案準備部署上線。請以資安 reviewer 的角色掃一次全部程式碼,逐項回報:
1. 有沒有任何金鑰、密碼、token 被寫死在程式碼裡?
2. 使用者輸入(聯絡表單)有沒有被直接塞進 innerHTML 之類會執行 HTML 的地方(XSS 風險)?
3. .gitignore 是否涵蓋 node_modules、.env、系統暫存檔?
4. 外部連結的 target="_blank" 有沒有加 rel="noopener noreferrer"?
每一項給我:通過/不通過 + 檔案位置 + 修法。

這個專案通常會全數通過或只有小修。重點不是這次掃到什麼,而是把「掃描」固定成部署前的必經站——以後專案變複雜、開始接 API 金鑰時,這個習慣會救你。

部署:GitHub → Vercel,這次不看筆記

流程和第 4 課一模一樣,這次試著不翻筆記做完:GitHub 建一個全空的 private repo(不要勾 README)→ git remote add origin ...git push -u origin main → Vercel「Add New → Project」→ Import → Deploy。卡住的話才回去翻第 4 課,或把錯誤訊息直接貼給 Claude Code。

部署完成拿到 https://my-portfolio-xxxx.vercel.app,先做兩件驗收:用手機開一次(桌機沒跑版不代表手機沒跑版),在正式網址上再送一次聯絡表單(本機能送不代表線上能送,環境不同就要重測)。

綁網域 + 最終驗收

作品集網站值得一個自己的網域:.com 一年約 10~15 美元,到 Cloudflare Registrar 或 Namecheap 買,回 Vercel 的 Settings → Domains 加上網域,照後台指示到網域商加 A 紀錄和 CNAME(細節第 4 課實戰第 6 步)。等 DNS 生效、狀態打勾後,跑最後的上線檢查清單:

上線前最終驗收清單:功能、資安、體驗三大類十個檢查項

十項全過,恭喜——你完成了一次沒有任何人牽著手的從零到上線。這個流程你已經走得動第二次、第三次,以後不管是幫自己做、幫朋友做、還是接案做,都是同一套。

全課程常見坑總整理

八堂課走完,把整條路上最常摔的 10 個坑做成一張地圖,以後卡住先來這裡對號入座:

全課程十大常見坑地圖:依建站、表單、部署、迭代四階段分類

坑 1:需求一句話,成品猜三天。「幫我做一個作品集」這種 prompt,AI 只能瞎猜。解法就是這堂課第 1 步的一頁需求文件:目標、區塊、風格、驗收條件,四欄寫齊再動工。

**坑 2:zsh: command not found: npm。**環境沒裝好就想跑專案。這代表 Node.js 沒安裝或終端機抓不到它,回第 3 課的環境安裝段,或直接把這行錯誤丟給 AI:「我在 macOS,出現這個錯誤,一步一步教我裝好 Node.js。」

坑 3:網站只有自己看得到。localhost:3000 是「我自己的電腦」,傳給朋友必定打不開。不是壞掉,是還沒部署——第 4 課整堂在解決這件事。

坑 4:一次餵十個需求,AI 全面翻車。「幫我加深色模式、換字體、改配色、加動畫、然後修手機版」——五件事混在一起,壞了你也不知道是哪件弄壞的。鐵律:一次一件事,驗證完 commit,再下一件

坑 5:AI 幻覺出不存在的套件。

npm ERR! 404 Not Found - GET https://registry.npmjs.org/some-package
npm ERR! 404 'some-package@^2.1.0' is not in this registry.

AI 有時會自信滿滿地引用一個根本不存在(或名字記錯)的套件。看到 404 not in this registry,把錯誤原文貼回去:「這個套件不存在,換一個真實存在且維護中的替代方案。」順帶一提,這也是資安議題:攻擊者會搶注這些「AI 常幻覺的套件名」放惡意程式(第 6 課講過的 slopsquatting),所以裝任何冷門套件前先看一眼它的 npm 頁面。

**坑 6:表單收到的信是空的。**送出成功、信也來了,但內容一片空白——幾乎都是 <input> 忘了寫 name 屬性。沒有 name,瀏覽器打包 FormData 時就會跳過那個欄位。檢查每個欄位都有 name="..."

坑 7:Formspree 回 422 或收不到信。

{"errors":[{"message":"Form not found"}]}

看到 Form not found 幾乎都是 endpoint 網址抄錯(那 8 碼打錯一個字就找不到)。回後台複製完整網址重貼。另一種是送出成功但信箱沒信:先看 Formspree 後台 Submissions 有沒有紀錄——有紀錄就是轉寄問題,檢查垃圾信匣、確認帳號 email 驗證過;沒紀錄才是前端沒送到。

**坑 8:金鑰 push 上 GitHub。**全課程最貴的坑。記住口訣:先換鑰匙、再滅火——立刻去服務後台作廢外洩的金鑰,然後才處理 git(.gitignore.envgit rm --cached .env)。因為舊金鑰永遠留在 git 歷史裡,光刪檔案沒有用。細節在第 4 課坑 3 和第 6 課。

**坑 9:本機好好的,Vercel 上 Command "npm run build" exited with 1。**正式建置比開發模式嚴格。部署前先在本機跑一次 npm run build,過了再 push;失敗就把 build log 最後幾十行貼給 Claude Code 修到過。

**坑 10:對話越長,AI 越笨。**改到第 30 輪,AI 開始忘記你前面的規矩、越改越歪。這不是它壞掉,是上下文塞爆了。解法是第 5 課的組合技:重要規矩寫進 CLAUDE.md(每次對話自動載入),然後果斷開新 session,把當前任務重講一次。

學完之後,下一步往哪走

八堂課,你從「完全不會寫程式」走到「能獨立把網站從零做到上線」。但 Vibe Coding 的地圖比網站大得多:

學習路線圖:Vibe Coding 建站之後,往 AI 自動化與 Claude API 開發兩條路走

兩條路值得繼續走:

  • AI 自動化:你已經會「叫 AI 做一次」,下一步是「讓 AI 自己重複做」——自動整理資料、自動發佈內容、排程跑任務,把日常的重複工作外包給 AI。這條路不太需要新的程式知識,吃的是你這門課練出來的「把需求講清楚」的功力。
  • Claude API 開發:這門課你是 AI 工具的「使用者」;學會呼叫 Claude API,你就變成 AI 功能的「製造者」——在自己的網站裡加 AI 客服、做自動摘要工具、開發自己的 AI 應用。你的作品集網站,就是第一個可以拿來加 AI 功能的實驗場。

這兩個方向我們都有對應的課程系列,從你現在的程度剛好接得上。

作業(這次是畢業製作)

  1. 完整走一遍:照今天的八個步驟,把你的作品集網站做出來、部署、綁上網域(網域選做),拿到正式網址。
  2. 實測表單:把網址傳給至少一個朋友,請他真的填一次聯絡表單,確認你信箱收得到。
  3. 回填作品集:把這門課做過的網站(第 2 課 Lovable、第 3 課個人品牌站)都放進作品區——你的作品集第一天就有三個作品。
  4. 寫一份自己的 SOP:開一個筆記,用自己的話把「從零到上線」的流程寫成 checklist。三個月後你要做下一個網站時,這份 SOP 比任何教學文都好用。

做完第 1 題,你就畢業了。你的網址,就是你的畢業證書——歡迎把它分享出來。我們下一個系列見。

#Vibe Coding#作品集網站#Formspree#綜合實戰#部署

← 回所有文章