分頁與無限滾動的 SEO:讓爬蟲讀得完整個列表
列表頁的分頁設計決定了 後面幾頁的內容能不能被發現。這件事的影響範圍常被低估:一個有 500 個商品、每頁 20 筆的分類,若分頁設計壞掉,就有 480 個商品進不了搜尋引擎。
分頁的角色
分頁頁面本身沒什麼搜尋價值
沒有人會搜尋「商品列表第 3 頁」。分頁的價值在於它是 通往內容頁的通道,爬蟲順著分頁連結才走得到第 250 個商品。
所以目標不是「讓分頁頁面排名好」,而是 讓爬蟲能走完整個列表。
網址設計
✓ /products?page=2
✓ /products/page/2
✗ /products#page=2
✗ /products(用 POST 或 JavaScript 換頁,網址不變)| 要求 | 說明 |
|---|---|
| 每一頁有 獨立網址 | 網址不變的分頁等於只有第一頁存在 |
| 網址可以 直接開啟 | 貼上網址就看得到第 3 頁的內容 |
| 不要用錨點 | # 後面的內容不會傳給伺服器 |
錨點與純前端換頁是最嚴重的錯誤
/products#page=2 的 # 之後不會傳給伺服器,對爬蟲來說它和 /products 是同一個網址。
同理,用 JavaScript 換頁但不改網址的實作,爬蟲只會看到第一頁。
每一頁都自我參照 canonical
不要把分頁的 canonical 都指向第一頁
<!-- 錯誤:在 /products?page=3 這一頁 -->
<link rel="canonical" href="https://example.com/products">這等於宣告「第 2 頁之後的內容不需要被收錄」,裡面的商品就不會被發現。
早期有這樣的建議,已經過時而且有害。
正確做法是每一頁指向自己:
<!-- 在 /products?page=3 這一頁 -->
<link rel="canonical" href="https://example.com/products?page=3">第 3 頁的正式版本就是第 3 頁。正規網址 管的是「同一份內容的多個網址」,而分頁的每一頁內容都不同。
也不要標 noindex
分頁應該保持可索引
標了 noindex 之後,爬蟲雖然還會追蹤連結(若是 noindex, follow),但那些分頁本身不會被收錄,也降低了它們在網站結構中的重要性。
分頁頁面沒什麼獨立搜尋價值,但它們是必要的通道。保持 index, follow 就好,也就是不寫這個標籤。
rel=prev 與 rel=next 的現況
<!-- Google 已不再使用這兩個標記 -->
<link rel="prev" href="https://example.com/products?page=2">
<link rel="next" href="https://example.com/products?page=4">寫了無害,但不要依賴它
Google 已公開宣布不再使用這組標記。寫了不會有壞處(部分瀏覽器會用它預取下一頁),但不要以為寫了就等於處理好分頁。
真正重要的是真實的超連結。
分頁連結必須是真的 a 標籤
爬蟲順著 <a href> 走。用按鈕或 <div> 加上點擊事件做的分頁,爬蟲完全走不到。
<!-- 爬蟲走不到 -->
<nav>
<button onclick="goToPage(2)">2</button>
<button onclick="goToPage(3)">3</button>
</nav>
<!-- 爬蟲可以走 -->
<nav aria-label="分頁導覽">
<ul>
<li><a href="/products?page=2">2</a></li>
<li><a href="/products?page=3">3</a></li>
</ul>
</nav>前端框架也要用真實網址
用路由套件時,讓分頁連結渲染成帶 href 的 <a>(而非攔截點擊的 <button>),這樣既保有用戶端切換的流暢,又保留可爬取的網址。
讓爬蟲不必一頁一頁走
只提供「上一頁/下一頁」的話,第 100 頁距離入口有 100 次點擊,這個 爬取深度 太深,爬蟲很可能不會走完。
<!-- 只有前後頁:第 100 頁太遠 -->
<a href="?page=2">下一頁</a><!-- 加上頁碼與首末頁:任何一頁都在幾步內 -->
<nav aria-label="分頁導覽">
<a href="?page=1">1</a>
<a href="?page=2">2</a>
<span aria-current="page">3</span>
<a href="?page=4">4</a>
<span>…</span>
<a href="?page=100">100</a>
</nav>頁面深度盡量控制在三層內
從首頁點三次能到的頁面,被收錄的機會明顯高於要點十次的頁面。除了分頁,也可以用 內部連結 從別處直接連到深層內容。
無限滾動
爬蟲不會滾動頁面
無限滾動靠捲動事件觸發載入。爬蟲不捲動,所以它只看到第一批項目,後面的內容等於不存在。
解法是 兩種瀏覽方式並存:
| 給誰 | 用什麼 |
|---|---|
| 使用者 | 無限滾動(體驗流暢) |
| 爬蟲與直接開網址的人 | 有真實網址的分頁連結 |
實作模式:
<!-- 內容區:無限滾動會往這裡追加 -->
<ul id="product-list">
<!-- 第一批項目,伺服器端就渲染好 -->
</ul>
<!-- 分頁連結:無限滾動可用時用樣式隱藏,但保留在 HTML 裡 -->
<nav aria-label="分頁導覽" class="pagination">
<a href="/products?page=2">2</a>
<a href="/products?page=3">3</a>
</nav>// 滾動時更新網址,讓使用者重新整理後回到同一個位置
history.replaceState(null, '', `/products?page=${currentPage}`);隱藏分頁連結要用 CSS,不要用 JavaScript 移除
用 display: none 隱藏的連結仍在 HTML 裡,爬蟲讀得到。用 JavaScript 把它從 DOM 移除就沒了。
也要注意不要把它藏成 隱藏文字 的形式,分頁連結是給使用者的功能性導覽,隱藏它是為了避免與無限滾動重複,這和塞關鍵字是兩件事。
檢視全部的取捨
| 分頁 | 檢視全部 | |
|---|---|---|
| 爬取次數 | 多(每頁一次) | 少(一次到底) |
| 單頁載入量 | 小 | 大 |
| LCP 與 CLS | 好 | 項目多時明顯變差 |
| 適合 | 項目數多 | 項目數少(數十筆內) |
判斷方式看項目數
- 數十筆 → 提供「檢視全部」頁面,並讓分頁的
canonical指向它。 - 上百筆以上 → 用分頁,每頁自我參照。
上千筆的「檢視全部」會是一個載入極慢的巨大頁面,那對使用者與 效能指標 都是災難。
分頁頁面的標題與描述
分頁頁面若全部共用同一組 標題 與 描述 ,就是全站重複的一種。加上頁碼區分:
<!-- 第 1 頁 -->
<title>男鞋|某某商店</title>
<!-- 第 3 頁 -->
<title>男鞋 - 第 3 頁|某某商店</title>檢查清單
| 項目 | 標準 |
|---|---|
| 每一頁有獨立且可直接開啟的網址 | 必備 |
分頁連結是真實的 <a href> | 必備 |
每一頁的 canonical 指向自己 | 必備 |
分頁頁面沒有 noindex | 必備 |
| 沒有用錨點做分頁 | 必備 |
| 提供頁碼而非只有前後頁 | 建議 |
| 無限滾動另外提供分頁連結 | 必備 |
| 分頁的標題含頁碼 | 建議 |
| 只有第 1 頁放進 sitemap | 建議 |
常見問題
分頁的每一頁都要有 canonical 指向自己嗎?
要。第 3 頁的正式版本就是第 3 頁。早期有把所有分頁的正規網址都指向第一頁的建議,那已經過時而且有害,因為那等於宣告第 2 頁之後的內容不需要被收錄,裡面的商品或文章就不會被發現。
rel=prev 和 rel=next 還需要寫嗎?
Google 已宣布不再使用這兩個標記,寫了不會有效果也不會有壞處。真正重要的是讓分頁之間有真實的超連結,爬蟲靠那些連結就能走完整個列表。
無限滾動對 SEO 有什麼問題?
爬蟲不會滾動頁面,所以只會看到第一批載入的項目,後面的內容等於不存在。解法是在無限滾動之外同時提供有真實網址的分頁連結,讓兩種瀏覽方式並存。
分頁的第 2 頁以後要不要標 noindex?
不要。標了之後爬蟲雖然還會追蹤連結,但那些分頁本身不會被收錄,而且降低了它們的重要性。分頁頁面通常沒什麼獨立搜尋價值,但它們是通往內容頁的必要通道,應該保持可索引。
檢視全部的頁面該怎麼處理?
項目數不多時,提供一個檢視全部的頁面並讓分頁的正規網址指向它是可行的做法。但項目數上千時那一頁會非常大,載入速度與版面穩定度都會變差,這時分頁才是正確選擇。