CSR 原理及常見問題
用純 React 開發 CSR(Client-Side Rendering)、SPA(Single Page Application) Web APP 時,儘管在頁面切換速度、性能上有卓越的優勢,但最麻煩的地方莫過於 SEO。
CSR 之所以快,原理就是 瀏覽器收到的 HTML 只有一個根元件
<div id="root"></div>
和一個打包好的 JS 檔,之後所有內容會由 JS 在 client 端瀏覽器執行後動態渲染出來
雖然 Google 現在有支援 CSR
渲染,但因爬蟲的 Crawl Budget(抓取資源預算) 有限,CSR 頁面常被延遲甚至忽略。社群平台(如 Facebook、LINE、Twitter) 抓取 og:image、og:title 等 Open Graph meta
時,也只讀原始 HTML,不會執行 JS,因此抓不到任何資訊。
為何 React Helmet 無法解決問題?
相信大家搜 react meta tags 都會看到 React Helmet
套件,可以在 React 應用中動態地管理 meta
,根據當前頁面自動更新 title、desciption、keywords 等,對 SEO 來說非常有用,但僅限於 Google 等搜尋引擎的爬蟲機器人
而且 React 19 後直接內建 react-helmet
的功能,可以直接在元件加入 meta 標籤了:React v19.1 官方文件
1 | function BlogPost({ post }) { |
儘管在網頁上確實能看到加入的那些 meta 標籤,但都是在頁面的 JS 載入之後才這麼做。對普通用戶來說,這完全沒問題——你打開瀏覽器,頁面載入完成,HTML 裡的 meta 標籤出現。但像 FB、LINE、WhatsApp 這類社群平台的爬蟲機器人可就沒那麼有耐心了。它們不會等你的 JS 執行完,而是直接抓取伺服器第一時間送出的 HTML,也就是那份空空如也、<head>
裡什麼都沒有的版本。
就想像你在烤披薩:React Helmet 就像是等披薩出爐後才加配料。你的朋友(使用者)吃到的是有滿滿配料的披薩,但社群平台的機器人就像急性子的朋友,一看到披薩出爐就立刻搶了一片,只有起司,沒有任何配料。
所以怎麼解決問題?幾種解法:
- 伺服器端渲染(SSR):
- 在 HTML 回傳給使用者之前就把 meta 標籤加進去。像是 Next.js 或 Gatsby 這類工具就能做到。等於是在披薩還沒出爐前就先放好配料,這樣就算是那位急著搶的人也能吃到完整版本
- Pre-build 或靜態網站(SSG):
- 預先建構(build)所有頁面,讓 meta 標籤直接寫死在 HTML 裡。這方式非常適合部落格、作品集等內容固定的網站
既有應用的替代方案
:- 使用像 Prerender.io 這類服務做中間人,它們會等你加好配料後再把披薩送出去——確保機器人也能吃到完整的頁面內容。
方法 1 和 2 都是比較繁瑣的流程,要重構整個請求 API 的程式,成本太高,也不想為了可以在社群分享時有特定標題跟縮圖就搞這些,所以最後透過方案 3 來解決
開始用
- 開發 useSEO hooks 取代在每個元件都寫死的 Meta Tags
- 設定 Prerender.io 服務
- 申請帳號
- 設定網站 URL
- 取得 API Token
- 在 Nginx 中設定 Prerender.io 的代理轉發
- 測試 Facebook、LINE、LinkedIn 等社群平台抓取 meta tags
建構可重複使用的 useSEO hooks
這邊避免在每個頁面都寫死 Meta Tags,改成開發一個 useSEO
hooks 來統一管理
完整程式碼很長,就放前面一些部分示意:
1 | export const useSEO = (seoData: SEOData): void => { |
之後在每個頁面中只需調用這個 useSEO
hooks,傳入對應的 SEO 資料即可:
1 | import { useSEO } from '@/hooks/useSEO'; |
但這些 meta tags 仍然是動態生成的,對於 Google SEO 來說有幫助,但社群平台的爬蟲來說還是抓不到,所以接下來需要用 Prerender.io 來解決這個問題。
設定 Prerender.io 服務
進官網跑完註冊流程後拿完 API Token,接著就可以依據每個人不同的 Intergration methods 來設定了,左側可以選自己的情況來快速跳到官方教學
那我自己是用 Nginx 來設定 Prerender.io 的代理轉發,就可以在不改動前後端程式碼的情況下,讓 Prerender.io 開一個 Headless Chrome 去跟我的 server 請求該路由的資料來預渲染 HTML
N
Nginx 設定
他們都有提供教學影片,告訴你在要複製哪一段及修改哪個地
照著影片操作,把相關的 Prerender 設定整合進自己網站的 nginx 設定檔,重點把 YOUR_TOKEN 換成自己的 API Token 即可
1 | ... |
Prerender.io 缺點
雖然實作起來很簡單暴力,大部分現有 CSR 前端框架 React, Vue, Angular 都可以直接使用,只需設定 server middleware。但缺點就是免費方案,只有每月 1000 次預渲染次數
查看結果
重啟 nginx 服務後,可以到網頁或直接指定測試 Prerender 是否觸發
1 | curl -I -A "facebookexternalhit/1.1" https://kostec.com/ |
成功就會看到 response header 多了:
然後回到自己 Prerender.io 的 dashboard 看,也可以看到請求紀錄:
成功畫面
網絡上也非常可以測試 Open Graph meta tags 的工具 Open Graph Debugger
FB、Discord、LINE 都成功正常擷取到 Meta Open Graph 標籤!
結論
以後遇到開發這種需要 SEO 跟以宣傳﹑行銷為主,又有大量內容的網站,還是直接一開始用 SSR 或 SSG 的方式來開發好 XD 不要找自己麻煩
若您覺得這篇文章對您有幫助,歡迎分享出去讓更多人看到⊂◉‿◉つ~
留言版