SPA 的使用者體驗很好,但 Google 不一定看得到
前端工程師喜歡 SPA(Single Page Application,單頁應用)不是沒有道理的。頁面切換不用重新載入、互動流暢得像原生 App、前後端分離讓開發更有效率——React、Vue、Angular 這些框架讓網站開發的方式徹底改變了。
但有一個問題一直困擾著使用 SPA 架構的網站:SEO。
傳統的多頁網站,每個頁面都是伺服器端產生的完整 HTML。Google 爬蟲來到你的頁面,直接就能讀到所有的內容。但 SPA 不一樣——伺服器只回傳一個幾乎空白的 HTML 檔案和一堆 JavaScript,內容是在瀏覽器端執行 JavaScript 之後才被渲染出來的。
Google 官方說他們的爬蟲已經能夠執行 JavaScript 和渲染 SPA 的內容了。這是事實,但事實的另一面是:這個過程並不完美,而且有延遲。
根據 Google 自己的說明,JavaScript 渲染是在一個「第二波」的索引流程中進行的。你的頁面可能被爬取後,要等好幾天甚至好幾週才會被渲染和索引。對於競爭激烈的關鍵字來說,這個延遲可能讓你錯過最佳的索引時機。
更實際的數據是:Merkle 在 2025 年的研究發現,純客戶端渲染的 SPA 網站,平均只有 65-70% 的頁面被 Google 成功索引,而 SSR(伺服器端渲染)的網站索引率接近 95%。
搜尋引擎爬取 SPA 時遇到的具體問題
要解決問題,首先得搞清楚問題出在哪裡。SPA 的 SEO 問題不是單一的,而是一連串的技術挑戰。
空白的 HTML 來源碼
打開一個純 SPA 網站的原始碼,你通常只會看到一個空的 <div id="app"></div> 和幾個 <script> 標籤。頁面的實際內容——標題、文字、圖片、連結——都是 JavaScript 執行後才動態產生的。
雖然 Google 的爬蟲可以執行 JavaScript,但其他搜尋引擎(Bing、Yahoo、百度)的 JavaScript 渲染能力參差不齊。如果你的目標市場包含中國,百度對 JavaScript 的處理能力就明顯比 Google 差。
動態 Meta 標籤的問題
SPA 的 <title>、<meta description> 等標籤通常是透過 JavaScript 動態設定的。如果搜尋引擎在 JavaScript 執行之前就抓取了頁面的 meta 標籤,你精心撰寫的頁面標題和描述就不會被正確索引。
社群平台的爬蟲問題更嚴重。Facebook、LINE、Twitter 的分享爬蟲通常不會執行 JavaScript,所以如果有人分享你的 SPA 頁面連結,社群平台上顯示的預覽圖和標題可能是空白的或是預設值。
路由和 URL 的問題
SPA 使用客戶端路由(Client-side Routing),頁面之間的切換不會向伺服器發送新的請求。如果你用的是 hash-based routing(URL 裡有 #),Google 完全不會把 # 後面的內容當作不同的頁面。
即使你用了 History API 來做乾淨的 URL(沒有 #),伺服器也需要正確地設定,讓所有的路由都回傳同一個 index.html。否則使用者直接在瀏覽器輸入某個子頁面的 URL,或是搜尋引擎爬蟲直接訪問子頁面,都會得到 404 錯誤。
解決方案一:SSR 伺服器端渲染
SSR(Server-Side Rendering)是目前最被推薦的 SPA SEO 解決方案。原理是在伺服器端就把 JavaScript 執行一次,產生完整的 HTML 頁面回傳給客戶端。搜尋引擎收到的是已經渲染好的完整頁面,不需要再自己執行 JavaScript。
主流的 SSR 框架
- Next.js(React 生態系):目前最成熟的 SSR 框架,由 Vercel 維護。提供頁面級的渲染策略選擇,你可以依需求選擇 SSR、SSG(靜態生成)或 CSR(客戶端渲染)。
- Nuxt.js(Vue 生態系):Vue 的 SSR 框架,功能和概念類似 Next.js。
- Angular Universal(Angular 生態系):Angular 的官方 SSR 方案。
SSR 的優點
首次載入就有完整的 HTML,搜尋引擎可以直接讀取所有內容。Meta 標籤在伺服器端就設定好,社群分享也能正確顯示預覽。首次載入的速度通常比純 CSR 快,因為使用者不需要等 JavaScript 下載和執行完成才看到內容。
SSR 的考量
伺服器負載會增加——每個請求都需要伺服器端渲染一次頁面,比起純 SPA 只需要回傳靜態檔案,伺服器的計算量大很多。開發複雜度也會提高,因為你需要確保程式碼在伺服器端和客戶端都能正常執行。
Hydration 的概念
SSR 頁面到達客戶端後,還需要經過一個叫做 Hydration 的過程——客戶端的 JavaScript 接管已經渲染好的 HTML,讓頁面變成可互動的 SPA。這個過程如果處理不好,可能會造成頁面閃爍或短暫的不可互動狀態。
解決方案二:靜態網站生成(SSG)
如果你的網站內容不需要即時更新(例如部落格、產品目錄、公司官網),靜態網站生成(Static Site Generation)是一個效能極佳的方案。
SSG 的概念是在建置(build)階段就把所有頁面渲染成靜態的 HTML 檔案。部署的時候只需要把這些靜態檔案放到 CDN 上就好。不需要伺服器端渲染,所以速度極快、伺服器負載極低。
Next.js、Nuxt.js、Gatsby 都支援 SSG。
SSG 的限制
每次內容更新都需要重新建置和部署。如果你的網站有幾萬個產品頁面,每次建置可能需要很長的時間。
ISR(Incremental Static Regeneration):Next.js 提供的 ISR 技術解決了這個問題。你可以設定頁面在特定時間間隔後重新產生,而不需要整個網站重新建置。使用者請求頁面時如果過期了,會先回傳舊版本,同時在背景重新產生新版本。
解決方案三:Pre-rendering
如果你已經有一個純 SPA 的網站,不想重寫成 SSR 或 SSG,Pre-rendering 是一個成本較低的折衷方案。
Pre-rendering 的做法是用一個無頭瀏覽器(Headless Browser)預先渲染你的 SPA 頁面,產生靜態的 HTML 快照。當搜尋引擎爬蟲來訪時,回傳這些預先渲染好的靜態頁面;當一般使用者來訪時,回傳正常的 SPA。
常用的 Pre-rendering 工具包括 Prerender.io 和 Rendertron。
Pre-rendering 的風險
Google 在官方文件中明確表示「不建議使用 cloaking(隱匿)」——也就是對搜尋引擎和使用者顯示不同的內容。Pre-rendering 的本質就是讓搜尋引擎和使用者看到不同版本的頁面。不過,只要兩個版本的內容是一樣的(只是渲染方式不同),Google 通常不會把它視為 cloaking。
但你需要確保預渲染的版本跟實際的 SPA 內容完全同步。如果 SPA 的內容更新了但預渲染版本沒有更新,搜尋引擎看到的就是過時的內容。
解決方案四:動態渲染
動態渲染(Dynamic Rendering)是 Google 在 2018 年提出的一種過渡方案。跟 Pre-rendering 類似,但動態渲染是即時進行的——伺服器偵測到搜尋引擎爬蟲時,用無頭瀏覽器即時渲染頁面回傳。
Google 在 2024 年的技術 SEO 指南更新中已經不再推薦動態渲染作為長期方案,而是建議直接使用 SSR。但如果你的網站很大、改造成 SSR 的成本太高,動態渲染可以作為過渡期的解決方案。
不管用哪種方案都要注意的 SEO 細節
選好了渲染方案之後,還有幾個 SPA 特有的 SEO 細節要處理。
Sitemap 的維護
SPA 的頁面可能是動態產生的,確保你的 sitemap.xml 包含所有你希望被索引的頁面。如果你的網站有很多動態路由(像是產品頁面),sitemap 要自動更新。
Canonical 標籤
SPA 的同一個內容可能有多個 URL 可以到達(帶參數的、不帶參數的、有 trailing slash 的、沒有的)。確保每個頁面都有正確的 canonical 標籤指向規範化的 URL。
內部連結
SPA 的客戶端路由通常用框架提供的 <Link> 元件。確保這些連結在 HTML 中被渲染成正常的 <a> 標籤,而不是透過 JavaScript 的 onClick 事件來導航。Google 爬蟲需要看到標準的 <a href="..."> 才能發現和追蹤連結。
載入狀態的處理
SPA 在獲取資料時通常會顯示一個 loading 狀態。如果搜尋引擎在資料載入完成之前就抓取了頁面,它看到的可能只是一個 loading spinner。確保 SSR 或 Pre-rendering 的版本已經包含了完整的資料。
該選哪個方案
這取決於你的具體情況:
新專案,內容為主的網站(部落格、媒體、電商):直接用 SSR 框架(Next.js 或 Nuxt.js)開始。這是最穩妥的選擇。
新專案,應用為主的網站(SaaS 工具、後台管理系統):大部分頁面用 CSR 就好(反正後台頁面不需要 SEO),但首頁、定價頁、功能介紹頁等面向公眾的頁面用 SSR 或 SSG。
已有的純 SPA 網站,SEO 需求不高:先做好基本的 meta 標籤動態設定、確保路由使用 History API、提交 sitemap。如果 Google Search Console 顯示大部分頁面都被正確索引了,可能不需要大改。
已有的純 SPA 網站,SEO 需求高:如果預算允許,改造成 SSR 是最根本的解決方案。如果預算有限,先用 Pre-rendering 或動態渲染作為過渡方案。
不管選擇哪個方案,都要定期用 Google Search Console 監控索引狀態,用「網址審查工具」測試 Google 是否能正確渲染你的頁面。如果你的團隊對 JavaScript SEO 不熟悉,建議找具備技術 SEO 能力的網頁設計公司協助。SEO 不是一次設定好就不管的事情,特別是在前端技術快速變化的環境下。