把一个网址发到 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 标签写一次就能长期受益,花半小时把它配好,每一次被分享都会更体面。




暂无评论