[CODE]

為什麼你的 OG 圖片在 LINE 上不顯示:六個要確認的地方

LINE 分享出去是空白卡片,不管原因是哪個,症狀都一樣。這是我在一家恆春民宿網站上花了三個小時的紀錄——Facebook Sharing Debugger 顯示正確圖片,LINE 還是空白,最後找到的診斷順序。

2 min read AI 生成
og seo web debugging

恆春民宿的口碑傳播靠 LINE。客人住完,傳連結給群組:「這家不錯,看看。」朋友看到預覽卡片,點進去,詢問日期。OTA 佣金比多數人以為的高很多,每個直客詢問都有價值。我在幫這一帶的幾家民宿建直訂基礎建設——廣告、落地頁、訂房流程、追蹤——後端做得再完整,分享出去的連結如果不顯示,一切都是白費。

那次要排查的是一個靜態 Astro 網站,部署在 Firebase Hosting 上。og:image 標籤在 HTML 裡,圖片 URL 直接開得起來,Content-Type 正確,Cloudflare 快取清過了,Facebook Sharing Debugger 顯示正確的預覽圖。LINE 還是空白卡片。

問題不在我確認過的任何一項。有六種完全獨立的失敗模式,症狀全部一樣:空白卡片、沒有錯誤訊息、沒有任何診斷訊號。每種需要不同的修法。順序不對,就會花一個小時反覆確認早就沒問題的東西。

直覺想到的第一個工具給你看的是假的

反射動作是打開 devtools 看 <head>。不要這樣做。Chrome Elements 面板顯示的是 JavaScript 渲染後的結果,不是 LINE 爬蟲拿到的東西。LINE 的爬蟲不跑 JavaScript。前端框架在 hydration 後才動態注入 og:image,爬蟲完全看不到。瀏覽器裡看起來正確,但問題根本不在那裡。

唯一可靠的確認方式是直接模擬爬蟲行為:

curl -A "facebookexternalhit/1.1" https://yoursite.com/some-page | grep og:image

輸出裡沒有標籤,就先修渲染層。可能是 SSR 沒有在伺服端輸出標籤、模板有問題、或是標籤被 JavaScript 動態注入而不是伺服端渲染。後面所有步驟都假設標籤已經出現在 HTML 原始輸出裡了。

六種斷法,同一個症狀

圖片路徑是相對路徑。 og:image 必須是絕對 URL。爬蟲沒有 base URL 可以解析,/images/og-cover.jpg 對它等於什麼都沒有。靜靜失敗,沒有任何提示。

圖片太小。 Facebook 和 LINE 對低於 200×200 像素的圖片直接略過,不通知。og:image 指到頁面現有的縮圖,爬蟲抓到了,丟掉,不說原因。實際目標是 1200×630,填滿預覽卡片,不出現黑邊。

Content-Type 錯了。 對圖片 URL 跑 curl -I,看 Content-Type 標頭。application/octet-stream 而不是 image/jpegimage/png,部分爬蟲不把這個檔案當圖片處理。沒有明確設定 MIME type 的 S3 bucket 和 CDN 是常見原因。

沒有提供圖片尺寸資訊。 og:image:widthog:image:heightog:image:type 三個 meta 標籤都沒有的話,LINE 爬蟲必須自己抓圖片、解碼、才能確認尺寸是否符合要求。CDN 夠慢或爬蟲時間不夠時,它直接放棄,不顯示圖片,也不告訴你原因。補上這三個標籤,爬蟲就能跳過抓取和解碼的步驟。這和圖片太小是兩個不同的問題:圖片可以是正確的尺寸,但如果爬蟲沒辦法快速確認,一樣會被丟掉。

防護機制把爬蟲擋住了。 Cloudflare 的 Under Attack 模式、WAF 規則、rate limiting 對爬蟲和攻擊者一視同仁。用爬蟲 UA 明確測試:

curl -A "facebookexternalhit/1.1" https://yoursite.com/

回來的是 Cloudflare 攔截頁面,這個網域所有分享出去的預覽卡片都是空白,直到在防火牆規則裡把爬蟲 User-Agent 加入白名單。

LINE 自己的 72 小時快取。 這才是那三個小時真正的原因。

LINE 有自己的 OG 快取,TTL 72 小時。這個快取和你的伺服器、CDN、任何你能控制的快取都沒有關係。清 Cloudflare 沒用。重新部署也沒用。Facebook Sharing Debugger 可以顯示正確圖片,LINE 同時還是空白——因為 LINE 爬蟲最後一次抓這個頁面是在你更新 og:image 之前,在 TTL 到期或你手動觸發之前不會再抓。

修法是 LINE 開發者後台的 LINE Page Cache Refresh Tool。貼上 URL,強制重新爬取,幾分鐘後卡片就更新了。

Facebook Sharing Debugger 是診斷的轉折點

Debugger 顯示爬蟲實際看到的東西:解析出來的 og: 標籤、偵測到的圖片尺寸、圖片是否可達、具體的錯誤訊息。這些資訊是空白卡片完全不提供的。Debugger 的作用是區分「客戶端問題」和「平台快取問題」,這兩類需要完全不同的應對方式。在步驟 3 之後跑 Debugger,不是之前。

  1. curl 加爬蟲 UA——og: 標籤在 HTML 原始輸出裡?
  2. og:image 是絕對 URL?直接在瀏覽器能開?
  3. curl -I 圖片 URL——Content-Type 標頭、HTTP 狀態碼
  4. Facebook Sharing Debugger——解析結果、尺寸、可達性、錯誤訊息
  5. Debugger 顯示正確圖片,LINE 還是空白:LINE Page Cache Refresh Tool
  6. Debugger 連頁面都拿不到:防護機制白名單問題
  7. Debugger 顯示舊圖:清 CDN 快取,再跑一次步驟 4

步驟 1–4 大概十分鐘。5–7 各五分鐘。那三個小時,是因為在步驟 4 之前就先試了步驟 7。清快取沒效,繞回去從 1–3 再找一遍,Debugger 是第二輪才找到的。

這次排查最後進了生產

那次除錯之後,我把結果做成 SEO 元件,現在所有維護中的 Astro 網站都用這套。每個頁面都輸出 og:image:widthog:image:heightog:image:type,和圖片 URL 一起輸出。所有圖片路徑在建構時都過一個 absolutize 函式:絕對 URL 直接通過,根相對路徑自動加上網域前綴。模板作者和之後維護內容的人都不需要記這件事,元件負責強制執行。

LINE 的快取問題沒有自動化解法。頁面第一次被分享時需要手動觸發,og:image 有任何變更之後也要再觸發一次。這是上線前就要讓業主知道的工作流程,不是分享沒效果一週後才說的事。

對一家靠 LINE 群組引流的民宿來說,預覽卡片空白不是體驗問題。那個引薦根本沒有發生。

沒有進來的詢問是看不見的。業主看得到後來訂下來的,看不到停在空白卡片那裡的。