Headless CMS 儲存草稿,storefront 卻通常只讀已發布內容與 cache。預覽功能要建立一條受保護路徑,讓授權編輯者以 draft perspective 查詢、進入正確 URL、看到即時或近即時更新,離開後再恢復 production 模式。
只加 ?preview=true 不能構成安全預覽,因為任何人都能猜到網址。
從授權 endpoint 建立 session
CMS 或 Studio 開啟預覽時,呼叫前端的 enable endpoint,帶入簽名 secret、document 和目標路由。Server 驗證來源與 secret 後建立 HttpOnly、Secure、短效 preview cookie,再 redirect 到允許的內部路徑。
不要接受任意外部 redirect,避免 open redirect。Draft read token 只放 server 環境,不輸出到 client bundle、URL 或 log。Disable endpoint 清除 session,過期也要自動失效。
Route resolver 連接 document 和頁面
定義 article slug、page path、product reference、locale 和 market 如何組成 preview URL。新 document 尚未有 slug 時,可以導向 preview shell 並提示缺少欄位;slug 修改時,Studio 和 storefront navigation 都要更新。
Sanity Presentation Tool 的 configuration可使用 document location resolvers 和 preview mode endpoints。其他 CMS 也需要同等的 route mapping,不能靠編輯者手動複製網址。
Preview query 和 production query 分離
Production 使用 published perspective、CDN 與正常 cache;preview 使用 drafts perspective、授權 token,並避免共享公開 cache。將 preview flag 傳入資料層,而不是在每個元件各自判斷。Shopify 商品資料仍可來自 Storefront API,但要清楚標示連的是測試或正式商店。
如果 draft reference 指向未發布內容,query 要能解析;若指向不存在商品,預覽應顯示可操作警告,不要整頁空白。
Live update 與 visual editing
Live preview 可透過 CMS subscription、Live Content API 或框架 loader 更新。Sanity 的 Content Source Maps 能把 query result 映射回 document 和 field,支援 overlay 與 click-to-edit。這些 metadata 只在 preview 使用,避免 stega 或 draft 資料進入 production SEO 輸出。
即時更新也要處理斷線、舊 request 和高頻輸入。顯示 connection 狀態,必要時提供手動 refresh,不讓編輯者誤以為內容已發布。
多語系和裝置要能切換
預覽 UI 提供 locale、market、viewport 和 route navigation,並保持在 preview session。檢查缺語系、fallback、不同 slug 和 market-specific 商品。內容存在於 CMS,不代表該商品已在對應 Shopify channel 可售。
行動 viewport 預覽可協助編輯,但不能取代真機 QA。外層 Studio iframe 也可能影響 cookie、navigation 和 responsive width,需要實測。
發布後驗證不是預覽的一部分
編輯者按下 publish 後,webhook 應觸發相關 cache revalidation。系統回報事件成功、受影響 URL 和最新版本,再由 production URL smoke test 確認。預覽正確只能證明 draft path,不能證明 CDN 已更新。
驗收涵蓋授權成功與失敗、session 過期、任意 redirect、未發布 document、slug 變更、draft reference、live update、locale、停用 preview 和 production 隔離。將 token、route、query、cache 和 publish owner 記入 runbook,才能讓預覽長期可用。