工程日記・第十一天:Google 說不 —— 1,700 頁 SEO 緊急修復
Google Search Console 給我們的網站拋出了六個不同的錯誤類別——5xx 崩潰、canonical 錯誤、重複頁面、404、1,700+ 未發現的 URL,以及 61 個 Google 抓取後明確拒絕索引的頁面。我們在一個 session 中逐一診斷修復:locale 感知的 generateStaticParams、53 個文件的自引用 canonical URL、一個 301 重定向、IndexNow 批量提交、Header 導航重構,以及爲 184 個內容貧乏的機型頁面生成獨特內容。構建時間從 2 分鐘飆升到 12 分鐘,所以我們也修復了。七次提交,零個頁面仍然有問題。
痛苦儀表盤
當你上線一個擁有 3,400+ URL 的多語言網站,一週後打開 Google Search Console,你應該做好壞消息的心理準備。我們沒有。
六個錯誤類別盯着我們,每個都是"Google 無法或不願索引你的頁面"的不同變體:
- 服務器錯誤 (5xx) — 100+ URL 渲染崩潰
- 含正確 canonical 標籤的備用頁面 — 118 個頁面 canonical 引用錯誤
- 無用戶選定 canonical 的重複頁面 — 2 個頁面
- 未找到 (404) — 1 個遺留 URL
- 已發現 - 尚未索引 — 1,720 個頁面 Google 發現但未訪問
- 已抓取 - 當前未索引 — 61 個頁面 Google 訪問後明確拒絕
每個類別有不同的根因。每個需要不同的修復。這是在一個 session 中診斷並解決全部六個問題的故事。
Bug 1:5xx 大屠殺
超過 100 個 URL 返回服務器錯誤。模式立即顯現:所有動態頁面的非英文 locale 變體都在崩潰。/fr/operators/netjets — 500。/zh/airports/teterboro — 500。/es/case-studies/diplomatic-charter — 500。英文版本正常。
根因:六個頁面文件中的 generateStaticParams() 只返回 { slug },沒有包含 { locale, slug }。在 Next.js App Router 中,當頁面位於 [locale]/[slug] 下時,靜態參數必須包含兩個動態段。沒有 locale,Next.js 只預渲染默認 locale 變體。其他 locale 在運行時命中服務器,由於這些是靜態數據頁面沒有服務端回退,直接崩潰。
修復是機械性的,但必須精確應用於六個文件——運營商、空腿航班、機場、機場 FBO、單個 FBO 詳情和案例研究。六個文件變更,約 1,065 個 URL 從 5xx 恢復到 200。本次 session 中影響最大的單次修復。
Bug 2:Canonical 的背叛
118 個頁面被標記爲"含正確 canonical 標籤的備用頁面"。這意味着 Google 發現了頁面,看到其 canonical URL 指向其他地方,決定索引 canonical 目標。我們的法語、中文和西班牙語頁面全部將 canonical 指向英文版本。
問題出在共享 SEO 工具函數 buildAlternates()。它總是生成英文裸 URL 作爲 canonical,不管哪個 locale 在渲染。正確行爲:每個 locale 變體應該自引用。/fr/fleet/citation-x 的 canonical 應該是 /fr/fleet/citation-x,而不是 /fleet/citation-x。
但修復工具函數只是一半的戰鬥。每個調用 buildAlternates() 的頁面都需要傳入 locale 參數。更糟的是:34 個頁面使用 export const metadata——一個無法訪問路由參數的靜態導出。每一個都必須轉換爲能從 params 提取 locale 的動態 generateMetadata() 函數。53 個文件在一次提交中變更。
Bug 3:幽靈 URL
一個 404:/quote。我們幾周前把頁面重命名爲 /contact,但從沒設置重定向。next.config.ts 中一行代碼:301 永久重定向,告訴 Google 將所有排名信號從舊 URL 轉移到新 URL。
Bug 4:1,720 個未發現的頁面
"已發現 - 尚未索引"意味着 Google 找到了這些 URL(在我們的 sitemap 或內部鏈接中)但還沒有派爬蟲訪問。兩個行動:首先,通過 IndexNow 協議提交全部 3,428 個 URL,同時 ping Bing、Yandex、Seznam 和 Naver。其次,分析內部鏈接結構,發現關鍵 hub 頁面——/airports、/operators、/case-studies——只在 footer 中有鏈接,header 導航中缺失。
Header 是網站上最重要的內部鏈接元素。每個頁面都渲染 header,意味着其中的每個鏈接都獲得最大的抓取優先級。我們重構了 header 導航:Destinations 變成下拉菜單,包含 Destinations hub、Airports、Operators 和 Case Studies。About 下拉新增 For Agents 鏈接。四個語言的翻譯文件全部更新。
Bug 5:內容貧乏的拒絕
"已抓取 - 當前未索引"是 Search Console 中最令人擔憂的狀態。意味着 Google 實際訪問了頁面、評估了內容,然後決定不值得索引。這是主動拒絕。
61 個頁面被拒絕。模式:主要是機隊 catalog 頁面及其 locale 變體。診斷:我們的機隊有兩層數據。15 架飛機有豐富詳細的內容——400+ 字的雙語描述。但 184 架飛機是僅有 catalog 數據的條目。這些頁面使用共享的 CatalogDetailPage 組件,爲同一類別的所有飛機顯示相同的類別級描述。40 多架輕型噴氣機共享相同段落。Google 正確地將其識別爲內容貧乏的重複內容。
修復:構建 generateAircraftIntro() 函數,根據每架飛機的具體規格——製造商、航程分類、客艙尺寸、巡航速度等級、WiFi 可用性和定價——創建獨特的介紹段落。184 個 catalog 頁面現在各自以獨特段落開頭,後接類別級內容。
Bug 6:構建時間回退
修復所有 locale 變體的 generateStaticParams 後,引入了新問題:Vercel 構建時間從 2 分鐘飆升到 12 分鐘。數學很簡單——從預渲染約 199 個頁面變成 796 個(199 機型 × 4 locales)。
解決方案:只預渲染需要預渲染的。15 個詳細機型頁面有豐富內容值得靜態生成。184 個 catalog 頁面更輕,可以按需渲染。generateStaticParams 從返回 796 頁改爲 60 頁(15 × 4 locales)。構建時間恢復到合理範圍。
今天發佈的內容
| 提交 | 修復 | 文件變更 | 影響頁面 |
|---|---|---|---|
7f6b740 | 爲 6 種頁面類型添加 locale 到 generateStaticParams | 6 | ~1,065 URL 從 5xx 恢復 |
df49944 | 所有 locale 變體的自引用 canonical URL | 53 | 118+ 頁面 canonical 修正 |
9737f12 | 301 重定向 /quote → /contact | 1 | 1 個遺留 URL 保留 |
a70b825 | Header 導航添加 airports/operators/case-studies | 5 | 所有頁面(改善內部鏈接) |
f39b583 | 184 個 catalog 頁面的獨特機型描述 | 1 | 736 頁面(184 × 4 locales) |
2528dc2 | 僅在構建時預渲染 15 個詳細機型 | 1 | 構建時間:12min → ~5min |
| 合計 | 67 文件 | ~3,400 URL 受影響 | |
另外:通過 IndexNow 提交 3,428 個 URL 以加速重新抓取。
經驗教訓
國際化不只是翻譯。添加 next-intl 和翻譯字符串只是第一步。第二步是確保 SEO 基礎設施的每一個環節——靜態參數、canonical URL、metadata 函數——都是 locale 感知的。我們有翻譯,但忘了教框架。
靜態 metadata 是陷阱。在 Next.js App Router 中,export const metadata 看起來簡潔。但頁面一旦在 [locale] 等動態段下,你就需要運行時訪問路由參數,即需要 generateMetadata()。我們一次性轉換了 34 個頁面。教訓:多語言站點從第一天起就用動態 metadata。
內容貧乏是真實信號。Google 拒絕 catalog 頁面不是因爲技術錯誤,而是因爲內容確實貧乏——同一類別 40+ 頁面共享相同段落。修復不是 meta 標籤或配置變更,而是寫更好的內容。
構建時間是功能。從 2 分鐘部署變成 12 分鐘不只是不便——它改變了你的發佈方式。快速迭代依賴快速反饋循環。我們選擇減少預渲染、按需緩存,用 catalog 頁面首次訪問的延遲換取 60% 的構建時間縮減。
SEO 不是你發佈一次的功能。它是與網站野心成正比地斷裂的基礎設施。10 頁的營銷網站不需要這些。3,400 頁的多語言平臺,動態路由、四個 locale、199 架飛機?關於靜態生成、canonical URL 和內容唯一性的每一個假設,都在規模面前被壓力測試。今天我們通過了測試——但只因爲 Google 告訴我們正在失敗。
準備好飛行了嗎?幾秒鐘獲取個性化包機報價。
訂閱資訊
空腿航班優惠、新航線與航空洞察,直達您的郵箱。