React SPA SEO:prerender、route manifest 與 sitemap 同一來源

讓 React 公開 route 在初始 HTML 有內容與 metadata,並從同一 manifest 產生 prerender、canonical、robots、404 與 sitemap。

React SPA 可以在瀏覽器呈現完整內容,但 crawler、link preview、無 JavaScript client 與錯誤監控首先看到的是 HTTP status 和初始 HTML。若所有 path 都回同一空 index.html ,title/canonical 要等 client effect 才出現,搜尋與分享訊號就容易不一致。Prerender 的目標是讓公開、穩定 route 在 build 時已有可信 HTML,不是把 dashboard 或個人資料靜態化。 截至 2026-07-29,Google JavaScript SEO 文件仍要求 crawlable links、正確 status 與可理解 metadata;sitemap 指南要求 fully-qualified canonical URLs,且 lastmod 應反映真實重大更新。React 官方 server APIs 可把 component tree render 成 HTML;Vite production build 提供資產基礎。 實作步驟 建立唯一 route manifest,記錄 path、route key、indexable、title/description、canonical、language、data source、updated_at。Navigation、prerender、sitemap 與 smoke test都讀它,避免手寫四份 route list。 export const publicRoutes = [ { path: "/", indexable: true, key: "home" }, { path: "/articles", indexable: true, key: "articles" }, { path: "/contact", indexable: true, key: "contact" }, ] as const 在 vite build 後執行 prerender script。對每個 indexable route建立隔離 render context,等待必要 data,輸出對應 dist/<path>/index.html 。可使用 react-dom/server static/streaming API或 headless browser,但要 deterministic timeout與錯誤;任一路失敗應讓 build fail,不留下半套 HTML。 每頁 head 包含唯一 title、description、self-canonical、Open Graph URL/locale與適用 structured data。JSON-LD 用 JSON.stringify 並處理 < ,不插未信任 raw HTML。公開內容的 H1/主文在初始 HTML,內部連結有正常 href 。 設定 hosting fallback時分流:已 prerender static route回 HTML;hashed assets/API照實;client-only authenticated route可回 SPA shell;未知公開 URL回真正 404 page/status。不能用 / * /index.html 200 把所有 typo變 soft 404。 從 manifest/內容資料產生 sitemap,只列 indexable self-canonical絕對 URL。 lastmod 來自真實文章更新時間,不用每次 build current time。robots.txt 指向 production sitemap,staging/preview 應 noindex或受控,不和 production canonical混在一起。 build verifier讀每個 HTML,檢查 title、description、canonical、H1、lang、無 placeholder;解析 sitemap,確認 URL set與manifest完全相等、沒有 preview host/duplicate/non-200。另測 robots、404與每個 asset reference。 失敗與復原 prerender hang 通常是等待 networkidle 、未關閉 timer/socket或 route data無限 loading。改等待明確 app-ready marker,設 per-route timeout並列出失敗 path。不要忽略 route繼續 deploy。 所有頁 metadata相同時,head state 在 routes間未 reset或 renderer仍在首頁 context。每 route建立新 render context,加入 canonical/title uniqueness test,回滾最後可信 artifact。 sitemap有未發布/404 route時,修 source manifest/status filter並重新產生;不要手動刪 sitemap entry但保留 generator bug。若 lastmod 每次 build變更,改用 content timestamp。 custom domain仍舊內容時,比對 deployment domain與 cache-busted custom response/body hash;只在確認 cache mismatch後 purge並重新驗證。 驗證指令 npm run build rg -n &#x27;<title>|canonical|<h1|application/ld\\+json&#x27; dist curl -sS https://example.com/sitemap.xml | head curl -sS -o /dev/null -w &#x27;%{http_code}\n&#x27; https://example.com/not-a-real-page 用 script逐 route解析 initial HTML,不用 browser Elements作唯一證據;再用 browser domcontentloaded 驗 hydration無錯、navigation/互動正常。驗收 production custom domain 的 status、canonical、sitemap、robots、404與cache-busted內容。 官方來源 Google JavaScript SEO basics Google Build and submit a sitemap React Server APIs Vite Building for Production 延伸閱讀 在 技術文章 查看多語 SEO 與 Cloudflare 除錯。 從 課程總覽 實作 route-driven prerender。 可由 聯絡頁 提供有問題的 canonical URL。