Open Graph 协议插画:Q 版动漫女孩举着带大图的链接预览卡片,周围是分享与链接图标

Open Graph 协议是什么?让链接分享自带标题、描述和大图的 OG 标签完整指南

链接分享到 Slack、Discord、LinkedIn 时能否展开成带大图的卡片,取决于 Open Graph 标签。本文讲清 OG 的必填与常用标签、Twitter Cards、预览图规范、WordPress/Astro/Next.js 的实现方式,以及调试工具和常见坑。

把一个网址发到 Slack、Discord、Telegram 或者 LinkedIn,有的链接会自动展开成一张带标题、描述和大图的卡片,有的却只是一行光秃秃的网址。差别就在于网页有没有正确设置 Open Graph 标签。

我自己维护着几个网站,每次上线新站或者改版,Open Graph 都是必检项之一。这篇把它的原理、必填标签、图片规范、各框架的实现方式和调试方法整理一遍,最后附一份检查清单。

Open Graph 协议是什么

Open Graph(简称 OG)是 Facebook 在 2010 年推出的一套协议,规范发布在 ogp.me。它的思路是基于 RDFa,在网页的 <head> 里用一组 <meta> 标签告诉外部平台:"这个页面的标题是什么、用哪张图、是什么类型的内容",让任何网页都能像 Facebook 里的一个"对象"一样被结构化地展示。

最基本的写法是这样的:

<meta property="og:title" content="文章标题" />

注意 OG 标签用的是 property 属性,而不是常见的 name。

它影响哪些地方

当你在某个平台粘贴链接时,平台的爬虫会去抓取这个网页,读取 OG 标签来生成预览卡片。目前读取 OG 标签的平台非常多:

  • Facebook、Messenger、Instagram 的链接预览(OG 的"老家")。
  • LinkedIn、Pinterest。
  • Slack、Discord、Telegram、WhatsApp、iMessage 等聊天工具的链接展开。
  • X(原 Twitter)主要使用自己的 Twitter Cards 标签,但在缺少对应标签时会回退读取 OG 标签。
  • 国内的情况比较复杂:微信对普通网页的分享卡片有自己的规则,公众号内或接入 JS-SDK 的页面可以自定义标题、描述和图片,直接粘贴链接时对 OG 标签的支持有限,不同场景表现也不一样;QQ、钉钉、飞书等对 OG 的支持程度也各有差异。做国内业务时,最好实际在目标平台里测一下。

四个必填标签

按照 ogp.me 的规范,每个页面都应该有以下四个标签:

  • og:title:内容标题,不需要带网站名。
  • og:type:内容类型,首页一般用 website,文章页用 article,此外还有 video.movie、music.song、profile、book 等。
  • og:image:预览图片的地址,必须是可公开访问的绝对 URL。
  • og:url:这个页面的规范地址(canonical URL),平台会用它作为这个链接的唯一标识。

常用的可选标签

实际项目里,下面这些也建议加上:

  • og:description:一两句话的描述,很多平台会显示在标题下方。
  • og:site_name:网站名称,比如"庄朋龙的博客"。
  • og:locale:语言地区,比如 zh_CN、en_US。
  • og:image:width 和 og:image:height:图片尺寸。提前告诉平台尺寸,首次分享时能更快渲染出图片,而不用等平台下载分析。
  • og:image:alt:图片的替代文字,对无障碍访问有帮助。
  • og:image:secure_url:图片的 https 地址。如果 og:image 已经是 https,可以不写。
  • og:image:type:图片 MIME 类型,比如 image/jpeg。

当 og:type 是 article 时,还可以使用 article 命名空间下的属性:

  • article:published_time:发布时间,ISO 8601 格式。
  • article:modified_time:最后修改时间。
  • article:author:作者。
  • article:section:所属栏目。
  • article:tag:标签,可以写多个。

一个完整的 head 示例

把上面的内容组合起来,一个文章页的 head 大概是这样:

<head>
  <meta charset="utf-8" />
  <title>Open Graph 协议是什么? | 庄朋龙的博客</title>
  <meta name="description" content="一篇讲清 Open Graph 标签、图片规范和调试方法的实用指南。" />
  <link rel="canonical" href="https://example.com/posts/what-is-open-graph-protocol" />

  <!-- Open Graph -->
  <meta property="og:type" content="article" />
  <meta property="og:title" content="Open Graph 协议是什么?" />
  <meta property="og:description" content="一篇讲清 Open Graph 标签、图片规范和调试方法的实用指南。" />
  <meta property="og:url" content="https://example.com/posts/what-is-open-graph-protocol" />
  <meta property="og:site_name" content="庄朋龙的博客" />
  <meta property="og:locale" content="zh_CN" />
  <meta property="og:image" content="https://example.com/images/og-cover.jpg" />
  <meta property="og:image:width" content="1200" />
  <meta property="og:image:height" content="630" />
  <meta property="og:image:alt" content="文章封面:链接预览卡片示意图" />
  <meta property="article:published_time" content="2026-10-17T22:00:00+08:00" />

  <!-- Twitter Cards -->
  <meta name="twitter:card" content="summary_large_image" />
  <meta name="twitter:title" content="Open Graph 协议是什么?" />
  <meta name="twitter:description" content="一篇讲清 Open Graph 标签、图片规范和调试方法的实用指南。" />
  <meta name="twitter:image" content="https://example.com/images/og-cover.jpg" />
</head>

Twitter Cards 怎么配

X 的卡片使用 twitter: 前缀的标签,并且用的是 name 属性。最关键的是 twitter:card,它决定卡片样式:

  • summary:小图卡片,图片显示在左侧或很小。
  • summary_large_image:大图卡片,图片占满卡片宽度,博客和产品页一般都用这个。

twitter:title、twitter:description、twitter:image 缺失时,X 会回退使用对应的 OG 标签,所以很多站点只额外写一个 twitter:card,其他复用 OG。如果需要关联账号,可以加 twitter:site(网站账号)和 twitter:creator(作者账号)。

图片怎么做才不出问题

预览图是 OG 里最容易出问题、也最影响效果的部分:

  • 尺寸:推荐 1200×630,约 1.91:1,这是 Facebook、LinkedIn 等平台大图卡片的通用比例。X 的大图卡片接近 2:1,同一张 1200×630 的图通常也能正常显示。
  • 地址:必须是 https 开头的绝对地址,不能写 /images/cover.jpg 这种相对路径。
  • 体积:各平台都有上限(常见在 5MB 到 8MB 之间),但实际上越小越稳,一般控制在几百 KB 以内,部分聊天工具对大图不太友好。
  • 格式:JPEG 和 PNG 最稳妥;WebP 大部分主流平台已支持,但为了兼容性,OG 图我仍然更倾向用 JPEG。
  • 构图:不同平台会按各自比例裁切,把标题文字和主体放在画面中间,四周留出安全边距,不要把重要文字贴着边缘。
  • 一页一图:首页、文章页最好各有自己的图,全站共用一张默认图会让分享出去的链接看起来都一样。

和 SEO 是什么关系

OG 标签不是 Google 的排名因素,加了不会直接提升搜索排名。但它决定了链接在社交平台和聊天工具里的展示效果:一张清晰的大图卡片和一行网址相比,点击率差别非常明显。社交渠道带来的流量、外链和品牌曝光,间接上对网站是有帮助的。

所以我的看法是:把 OG 当成"分享体验"的一部分来做,和 title、description、canonical 一起维护,而不是当成 SEO 技巧。

在常见建站方式中实现

WordPress

不需要手写,Yoast SEO、Rank Math 等主流 SEO 插件都会自动输出 OG 和 Twitter Cards 标签,默认使用文章标题、摘要和特色图片。在插件的"社交"设置里可以配置默认图片,在每篇文章的编辑页也可以单独设置分享标题、描述和图片。

注意不要同时启用多个会输出 OG 的插件(比如 SEO 插件加上 Jetpack 的分享功能),否则页面里会出现重复的标签,平台可能取到错误的那一组。

Astro

在布局组件里根据 props 输出即可,图片地址用 Astro.site 转成绝对地址:

---
const { title, description, image = "/og-default.jpg" } = Astro.props;
const canonical = new URL(Astro.url.pathname, Astro.site);
const ogImage = new URL(image, Astro.site);
---
<meta property="og:title" content={title} />
<meta property="og:description" content={description} />
<meta property="og:url" content={canonical} />
<meta property="og:image" content={ogImage} />
<meta name="twitter:card" content="summary_large_image" />

记得在 astro.config 里设置 site,否则 Astro.site 为空。

Next.js(App Router)

Next.js 提供了 Metadata API,在页面或布局里导出 metadata 即可:

export const metadata = {
  metadataBase: new URL("https://example.com"),
  title: "Open Graph 协议是什么?",
  openGraph: {
    title: "Open Graph 协议是什么?",
    description: "一篇讲清 Open Graph 的实用指南。",
    url: "/posts/what-is-open-graph-protocol",
    siteName: "庄朋龙的博客",
    images: [{ url: "/og-cover.jpg", width: 1200, height: 630 }],
    locale: "zh_CN",
    type: "article",
  },
  twitter: { card: "summary_large_image" },
};

metadataBase 会把相对路径补全成绝对地址。动态页面用 generateMetadata 函数按数据生成。

一定要服务端输出

这是最重要的一点:绝大多数平台的爬虫不会执行 JavaScript。如果你的站点是纯前端渲染(SPA),OG 标签是页面加载后用 JS 插进去的,爬虫拿到的就是一个空壳,预览自然什么都没有。OG 标签必须出现在服务器返回的 HTML 里,用 SSR、静态生成(SSG),或者针对爬虫做预渲染都可以。

最简单的验证方法:

curl -s https://example.com/posts/what-is-open-graph-protocol | grep 'og:'

能直接看到 OG 标签,才说明爬虫也能看到。

调试工具

  • Facebook 分享调试器(Sharing Debugger):developers.facebook.com/tools/debug,输入网址就能看到 Facebook 抓取到的所有标签和预览效果,还会提示缺失或错误的标签。改了标签之后点"重新抓取"(Scrape Again)可以刷新缓存。
  • LinkedIn Post Inspector:linkedin.com/post-inspector,功能类似,同样能刷新 LinkedIn 的缓存。
  • X 的 Card Validator:过去可以直接预览卡片,现在预览功能已经基本取消,比较实际的做法是发一条草稿或私信看实际效果。
  • 第三方预览工具:比如 opengraph.xyz 这类网站可以一次预览多个平台的效果,方便快速检查。

常见的坑

  • 图片用了相对路径:最常见的错误,平台根本拿不到图。
  • 改了图但预览不变:平台会缓存抓取结果,Facebook、LinkedIn 用上面的工具刷新;其他平台可以给图片地址加个版本参数,比如 og-cover.jpg?v=2。
  • og:url 和 canonical 不一致:比如一个带 www、一个不带,或者 og:url 写成了首页,导致所有文章被平台当成同一个链接,显示同一张卡片。
  • 爬虫被拦截:robots.txt 禁止了爬虫,或者 Cloudflare 的 Bot Fight Mode、WAF 规则、人机验证把 facebookexternalhit、LinkedInBot、Twitterbot、Slackbot 等平台爬虫挡在外面。这种情况下调试工具一般会报 403 或抓取失败,需要在防护规则里放行。
  • 图片太大或太小:超过平台上限会被忽略,太小(比如小于 200×200)可能只显示小图或不显示。
  • 页面需要登录或有地区限制:爬虫访问不到,自然没有预览。
  • 重复标签:多个插件或模板同时输出 OG,平台可能取第一组或最后一组,结果不可预期。

总结:上线前的 Open Graph 检查清单

  • 每个页面都有 og:title、og:type、og:image、og:url 四个必填标签。
  • 补上 og:description、og:site_name、og:locale 和图片的宽高、alt。
  • 文章页 og:type 用 article,并加上 article:published_time。
  • 加一行 twitter:card,博客一般用 summary_large_image。
  • 预览图 1200×630,https 绝对地址,体积控制在几百 KB,重要内容放在中间。
  • og:url 与 canonical 保持一致。
  • 标签在服务端输出,用 curl 能直接看到。
  • 确认 robots.txt 和 CDN 防护规则没有拦截平台爬虫。
  • 用 Facebook 分享调试器和 LinkedIn Post Inspector 检查,并在修改后刷新缓存。
  • 在目标平台(包括微信等国内应用)里实际发一次,看最终效果。

OG 标签写一次就能长期受益,花半小时把它配好,每一次被分享都会更体面。

暂无评论