← 回到 Blog
Vercel約 3 分鐘閱讀

GitHub 已經 push,Vercel 正式站卻還是舊內容:部署 freshness 排查筆記

分類VercelNext.js網站經營
標籤#部署檢查#Vercel#GitHub#SEO#Production QA
程式碼編輯器畫面,象徵 Next.js 內容站部署與 production freshness 排查

內容站最容易讓人誤判的狀況之一,是本機和 GitHub 都看起來正常,但正式網域還在服務舊頁面。尤其是每日新增文章時,git push 成功不等於讀者已經看到新文章;Vercel 顯示有 deployment,也不等於自訂網域已經切到最新 HTML。

UCAMC 的做法是先把問題拆開:內容是否真的進入 Git、Vercel 是否真的用那個 commit 部署、root-level 文章路由是否在 production 回 200、/blog 與 sitemap 是否都包含新 slug。這幾件事要分層驗證,才不會把部署 freshness 問題誤修成內容或 SEO 問題。

先確認 Git 內容,而不是先猜 Vercel 壞掉

第一步是確認目前工作區沒有漏掉的 Markdown 或版面修改。每日內容站維護常見失誤,是新文章存在於本機 content/blog,但沒有被 commit;或 commit 已存在,但 push 沒有成功送到 origin/main

可以先檢查:

git status --short
git log -1 --oneline
git ls-remote origin main

如果 git status --short 還有新文章未追蹤,正式站當然不會更新。若 git log -1git ls-remote origin main 指向不同 commit,問題也還在發布到 GitHub 之前,不需要急著調整 Vercel 設定。

再確認本機 production 產物是否真的有新路由

對 Next.js App Router 內容站來說,開發模式能看到文章,不代表 production build 一定會把 route 產出。UCAMC 文章 canonical URL 是 root-level /{slug},所以要直接測新文章根路徑,而不是測 /blog/{slug}

npm run lint
npm run build
npm run start -- --hostname 127.0.0.1 --port 3100

接著用 curl 檢查幾個入口:

curl -I http://127.0.0.1:3100/
curl -I http://127.0.0.1:3100/blog
curl -I http://127.0.0.1:3100/vercel-github-deployment-freshness-troubleshooting
curl -I http://127.0.0.1:3100/sitemap.xml

如果本機 production 的新文章就是 404,問題多半在 frontmatter、slug、content loader 或 build 輸出。若本機全部正常,才進入部署 freshness 層。

分辨「文章 route 404」和「列表還沒更新」

正式站 stale 可能有不同型態:

現象可能原因下一步
新文章 /{slug} 404Vercel 還沒部署新 commit,或 deployment 失敗查 deployment commit / build log
新文章 200,但 /blog 沒有新卡片列表頁快取或不同 deployment比對 HTML、sitemap、deployment URL
/blog 有新 slug,但 sitemap 沒有sitemap 產生邏輯或 stale response檢查 app/sitemap.ts 與 response
preview domain 新、自訂網域舊custom domain / edge cache freshness分開 poll 兩個 domain

排查時不要只看首頁截圖。首頁可能因為 Hero 只顯示最新一篇,讓人誤以為內容已更新;也可能首頁還在舊快取,但文章 route 已經能開。要把 //blog/{slug}/sitemap.xml 分開記錄。

自訂網域和 Vercel preview domain 要分開看

UCAMC 這類內容站通常同時有 Vercel preview domain 和正式自訂網域。兩者若回應不同,不要只說「production 壞了」,而要寫清楚哪一個 domain stale。

建議記錄格式:

ucamc-next-blog.vercel.app /{slug}: 200, contains slug
www.ucamc.com /{slug}: 404, stale body
ucamc-next-blog.vercel.app /blog: 200, contains title
www.ucamc.com /blog: 200, missing title

這樣回報時,Leon 或有 Vercel 權限的人可以直接判斷是否需要 dashboard redeploy、deploy hook、domain 設定檢查,或只是等 edge cache 更新。

SEO freshness:sitemap 和 canonical 也要一起看

內容站不只要讓讀者能打開文章,也要讓搜尋引擎看到一致 URL。新文章上線後,我會確認:

  • 文章 HTML canonical 指向 https://www.ucamc.com/{slug} 或 root-level canonical path。
  • /sitemap.xml 包含 https://www.ucamc.com/{slug}
  • /robots.txtSitemap: 指向正式 domain 的 sitemap。
  • 內部連結使用 /{slug},不是新建 /blog/{slug}

這裡的重點不是 keyword stuffing,而是避免搜尋引擎看到互相矛盾的 canonical、舊列表與新文章 route。

把 freshness 問題寫進維護紀錄

如果本機 lint/build/route 都正常,GitHub 也已經是最新 commit,但正式 domain 仍舊,這應該被報告成「部署 freshness 邊界」,不是把內容再改一次。重複修改 Markdown 只會產生更多 commit,卻不一定解決 Vercel 或 domain cache 問題。

一份好的紀錄至少包含:

  1. 新 commit hash。
  2. 本機 production route 檢查結果。
  3. Vercel preview domain 檢查結果。
  4. 正式 domain 檢查結果。
  5. /blog 與 sitemap 是否含新 slug。
  6. 是否需要 Vercel dashboard redeploy 或 token/deploy hook。

UCAMC 的日常判斷原則

如果你正在維護 Next.js 內容站,可以把這篇接在 Next.js 內容站上線後健康檢查模板 後使用。前者幫你確認 route 和 sitemap 是否合理;這篇則處理「GitHub 已更新,但正式站看起來沒更新」的中間地帶。

對長期經營的技術 Blog 來說,穩定發布比單次快速改版更重要。把 Git、build、deployment、edge cache 和 SEO freshness 分層記錄,下一次遇到正式站 stale,就能用證據判斷,而不是靠猜測重做內容。