如果選 OAuth 模式(§2 Part D),部署步驟照正確順序走(DNS → Build → Connect → Custom Domain),這一節你永遠不會用到。Pages 模式不需要 Routes,此節不適用。 這是兩個專案各花了 2 小時才學到的教訓。
部署後出問題,從上往下檢查,不要反過來:
| 順序 | 檢查 | 指令 | 說明 |
|---|---|---|---|
| ① | DNS | dig 網域 +short | 域有沒有指向 Cloudflare? |
| ② | Routes | Cloudflare 面板 → Workers Routes | api/* 指對 Worker 嗎? |
| ③ | 部署狀態 | Cloudflare → Deployments | 最新部署成功嗎? |
| ④ | config.yml 名稱 | grep "repo:" public/admin/config.yml | repo 名稱對嗎? |
| ⑤ | 頁面硬編碼 | grep "Layout title=" src/pages/*.astro | 有沒有覆蓋 Layout 預設? |
| ⑥ | 殘留檔案 | ls .github/workflows/deploy.yml | 有沒有舊 GitHub Pages 部署? |
| ⑦ | 程式碼 bugs | 最後才檢查 |
真實案例:ming-website 部署後打不開,我們先檢查了程式碼(⑦),查了 2 小時才回頭發現 DNS 沒有 A 記錄(①)。如果按這個順序,5 分鐘就能找到問題。
7.18 手機後台上傳圖片
已自動處理。 public/admin/index.html 內建一段 JS(約 40 行),在所有 Sveltia CMS 檔案上傳之前攔截:圖片 > 1MB → Canvas 壓縮至 1920px / quality 0.8 → 再交給後台上傳。
原圖 8MB → 瀏覽器壓到 ~500KB → 手機 4G 秒傳 → GitHub → Actions 轉 WebP
客戶視角:什麼都不用做。 打開後台、選照片、儲存。不需要壓縮 App,不需要學 Shortcuts 捷徑,不需要用 LINE 中轉。
服務哲學:客戶永遠不用改變他們自己的習慣。是我們要做到他們無須學習成本就能達成。
7.19 Cloudflare Worker / OAuth 除錯
Worker 壞了的三種查法
| 方法 | 指令 / 位置 | 說明 |
|---|---|---|
| 看 Log | Cloudflare 面板 → Workers & Pages → oauth-worker → Logs | 看有沒有紅色錯誤,特別是 401 (token expired) 或 500 |
| 即時 tail | npx wrangler tail oauth-worker | 看即時請求 + 回應,適合正在除錯 |
| curl 模擬 | curl -v https://你的網域/api/auth | 確認是回 302 (正常導向 GitHub) 還是 500/502 (有問題) |
最常見的三個錯誤
| 症狀 | 原因 | 解法 |
|---|---|---|
| OAuth 點下去跳空白頁 | REDIRECT_URI 跟 GitHub OAuth App 設的不一樣 | 檢查兩邊的 callback URL:https://你的網域/api/auth/callback |
| 後台登入後 500 Internal Error | 環境變數沒設(GITHUB_CLIENT_ID / GITHUB_CLIENT_SECRET) | Cloudflare 面板 → oauth-worker → Settings → Variables |
後台 /admin/ 404 Not Found | Workers Routes 沒設定 api/* 指到 oauth-worker | Cloudflare 面板 → 你的網域 → Workers Routes → 確認 api/* → oauth-worker |
Worker 跟 Pages 的關係(一句話)
Pages 處理靜態網站(你的網頁內容)
Worker 處理 API(OAuth 登入、回呼)
兩者獨立部署,靠 Routes 串接:api/* → Worker,其他 → Pages
[[#table-of-contents|← 回目錄]]
卷三:交付與商業(Business & Operations)
第 8 章:測試與交付檢查
👤 你:照 checklist 驗收、手機/桌面親測 — 🤖 AI:跑自動化腳本、產出驗收報告
8.0 audit.sh — 交付前的最後一道門
前置條件(首次執行前,一次性):
brew install lychee # dead link 檢查
chmod +x audit.sh # 確保可執行
audit.sh 存在於專案根目錄。一個指令,5 階段檢查:
./audit.sh # 跑預設網域
./audit.sh https://新客戶.com # 跑指定網域
| 階段 | 檢查 | 沒做客戶會遇到 |
|---|---|---|
| 1/5 | dead link | 客戶點連結跳 404,覺得你網站壞了 |
| 2/5 | Sitemap 網域正確 | Google 收錄到舊網域,新站永遠搜不到 |
| 3/5 | dist/ 無 localhost 殘留 | 網站出現 http://localhost 連結,客戶點了什麼都看不到 |
| 4/5 | dist/ 無舊 GitHub Pages 殘留 | 舊部署網址遺留在網站上,客戶困惑 |
| 5/5 | 全頁面回 200 | 某頁掛了你不知道,客戶先發現 |
目標:5/5 全部通過才能交付。
audit.sh 常見錯誤解析
跑完 audit.sh 後,不用每個紅字都緊張。以下是判定標準:
| 錯誤 | 例子 | 判決 | 說明 |
|---|---|---|---|
| 外部連結 404 | home-assistant.io/硬體/ 文件搬家 | ✅ 可不修 | 非本站控制,原作者改網址了 |
| 內部 sitemap 多出頁面 | /services/ 在 sitemap 但頁面已刪 | ⚠️ 查後台 | 有人在 CMS 發了又刪,從後台查 |
| 動態路由 test-slug 404 | destinations/test-slug/ 回 404 | ✅ 可不修 | 腳本用假 slug 測試,沒這篇文章正常 |
| canonical URL 錯誤 | 頁面 <link rel="canonical"> 寫著 github.io | ❌ 必須修 | Google 會收錄到舊網域,新站永遠搜不到 |
| 頁面不回 200 | /about/ 回 500 | ❌ 必須修 | 客戶點了會看到錯誤 |
| localhost 殘留 | dist/ 裡有 wrangler.json 的 "ip":"localhost" | ✅ 可不修 | Cloudflare adapter 開發設定,非真實 leak |
| 外部連結 403 | raspberrypi.com/software/ 被伺服器拒絕 | ✅ 可不修 | 對方網站擋 bot 或限制存取,非本站問題 |
8.1 全站頁面檢查(自動化)
# 掃描所有 Astro 頁面,檢查是否返回 200
for f in $(grep -l "^---" src/pages/**/*.astro 2>/dev/null); do
fname=$(echo "$f" | sed 's/src\/pages//' | sed 's/\/index\.astro$//' | sed 's/\.astro$//' | sed 's/\[\.\.\.slug\]//' | sed 's/\[slug\]/test/')
[ -z "$fname" ] && fname="/"
code=$(curl -s -o /dev/null -w "%{http_code}" "https://你的網域$fname")
echo "$code $fname"
done
8.2 手機版檢查(手動)
| # | 檢查項目 | 方法 | 通過 |
|---|---|---|---|
| 1 | 導航選單 | 打開漢堡選單 → 點每個連結 → 確認跳轉正確 | ☐ |
| 2 | 對比表 | 確認是直式卡片,不是左右滑動表格 | ☐ |
| 3 | 方案卡片 | 確認手機上是單欄排列(非擠成超小多欄) | ☐ |