OGP 的全稱是 Open Graph Protocol,由 Facebook 提出的社群分享預覽協定,我們在前面有簡單介紹過。
絕大部分的社群平台(除了 X, aka Twitter 之外),都抓取 og:x
的 meta 標籤產生分享在此平台的小卡片,例如 iT邦幫忙在 Facebook 分享時的卡片如下:
*iT邦幫忙之分享卡片
以這樣的分享卡片為例,如果我們在此頁面中的 <head>
元素下看 <meta property="og:*">
的元素,就可以看到以下內容,包含 site_name
、url
、type
、title
、image
及 description
。
<meta property="og:site_name" content="iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天">
<meta property="og:url" content="https://ithelp.ithome.com.tw">
<meta property="og:type" content="website">
<meta property="og:title" content="iT 邦幫忙::一起幫忙解決難題,拯救 IT 人的一天">
<meta property="og:image" content="https://ithelp.ithome.com.tw/storage/image/fbpic.jpg">
<meta property="og:description" content="iT 邦幫忙是 IT 領域的技術問答與分享社群,透過 IT 人互相幫忙,一起解決每天面臨的靠北時刻。一起來當 IT 人的超級英雄吧,拯救下一個卡關的 IT 人">
有了初步的認識,在我們的部落格之中,要怎麼在列表、文章等頁面加上這些 meta 的資訊呢?
首先,我們可以建立一個 OgHead.astro
的 Layout,放在 src/layouts/OgHead.astro
,填入 title
、description
、ogImage
、type
、noindex
、siteName
等基本資訊。
const {
title = '霍爾筆記',
description = '一位技術宅的探索足跡,分享技術大小事,主要聚焦於電腦科學領域,如網路通訊、全端開發;也涵蓋個人的隨筆記錄,學習心得。',
ogImage = '/og/default.png',
type = 'website',
noindex = false,
siteName = '霍爾筆記',
} = Astro.props;
其中 ogImage
就是被引用時顯示的圖片,而 noindex
則代表是否不要讓搜尋引擎收錄此頁面。
再來我們會寫一些簡單的邏輯,產出 Canonical URL(標準網址),放在 <link rel="canonical" href="..." />
的標籤內,告訴這是我們網站的標準網址。
指定 Canonical URL 的好處是讓分享的連結卡片有一致性,也對社群平台內部的 Cache 有幫助。舉例來說,我們在分享連結時可能會在網址中給出有沒有尾部的斜線(如 blog/1/
或 /blog/1
)、附上不同參數(如 /blog?utm=...
或 blog?ref=...
)。
再加上 Canonical URL 後,這些卡片的 Cache 都會指向同樣的 URL,而不會因為分享時給的連結有微小差異而指向不同的目標。產出 Canonical 可以簡單透過 new URL(Astro.url.pathname, site).href
來取得。
最後填入 Open Graph 和 Twitter Cards 的 meta 資訊,前置作業就差不多完成了。
---
const {
title = '霍爾筆記',
description = '一位技術宅的探索足跡,分享技術大小事,主要聚焦於電腦科學領域,如網路通訊、全端開發;也涵蓋個人的隨筆記錄,學習心得。',
ogImage = '/og/default.png',
type = 'website',
noindex = false,
siteName = '霍爾筆記',
} = Astro.props;
const site = import.meta.env.SITE;
const canonical = site && new URL(Astro.url.pathname, site).href;
const toAbsoluteUrl = (url: string) => (site && !url.startsWith('http') ? new URL(url, site).toString() : url);
const ogImageAbs = ogImage ? toAbsoluteUrl(ogImage) : ogImage;
---
{canonical && <link rel="canonical" href={canonical} />}
{noindex && <meta name="robots" content="noindex,nofollow" />}
<!-- Open Graph -->
<meta property="og:type" content={type} />
{canonical && <meta property="og:url" content={canonical} />}
<meta property="og:site_name" content={siteName} />
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:image" content={ogImageAbs} />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<!-- Twitter Cards -->
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:title" content={title} />
<meta name="twitter:description" content={description} />
<meta name="twitter:image" content={ogImageAbs} />
其中 ogImageAbs
是最終在預覽卡片中的圖片,由於 OG 的規格和各平台偏好絕對路徑,所以我們特別將相對路徑轉成絕對路徑,以避免一些平台可能無法顯示圖片。
最後,在原本的 src/layouts/Layout.astro
中插入 <OgHead />
,如下所示
---
import OgHead from './OgHead.astro';
---
<html lang="zh-TW">
<head>
<!-- ... -->
<OgHead />
</head>
<body>
<!-- ... -->
</body>
</html>
就大功告成,能夠在任何一個套用此 Layout 的頁面透過 OGP 來顯示較為精美的卡片。
如果要更進階一些的話,我們可以將上面用 const
定義的 title
、description
及圖片等等作為參數傳入,如此一來在分享文章時,就可以顯示文章標題、代表此文章的圖片。
如果要測試 Open Graph 的預覽卡片效果,可以使用 Facebook Sharing Debugger,這是一個用來檢查並重新抓取網頁 OGP 資料的工具。
當我們的網站已經上線,將公開的 URL 貼到 Debugger 的頁面中之後,就能產出預覽的卡片。
*Facebook Sharing Debugger 頁面
然而在還沒正式上線之前,我們在 Local 的網站需要測試 OGP,又不想部署到有 Public IP Address 伺服器,那麼透過 ngrok 這個工具來幫忙會是不錯的選擇。
這是一支跑在電腦裡的 Daemon,透過把 Local 的流量導入 ngrok 的伺服器,由他們提供公開而暫時的 URL,就能夠不必真的部署,簡單的的做測試,細節一點的內容可以參考我之前寫的淺談 ngrok 來理解其基本原理。
在 CLI 中安裝 ngrok 之後,執行 ngrok http http://localhost:4321
就能夠產出一組公開 URL,將其貼到 Facebook Sharing Debugger 中,預覽的卡片就能看到了。
*Facebook Sharing Debugger 預覽卡片結果