OG 图 1200×630 由来 + 微信/Twitter/LinkedIn/Slack 抓取规则差异

· 约 3 分钟 🃏 OG 卡片预览

链接发到微信、推特、Slack——会显示一张卡片预览,里面有标题、描述、缩略图。这背后是 Open Graph Protocol(OGP),但每个平台的解析规则不同,缓存策略不同,对图片尺寸的容忍度不同。

OG 协议核心字段

字段含义是否必填
og:title标题(可与 <title> 不同)
og:description一句话描述
og:image卡片图片绝对 URL
og:url规范 URL(避免 UTM 参数干扰)
og:typewebsite / article / product / video…推荐
og:site_name站点名推荐
og:localezh_CN / en_US推荐
og:image:width / og:image:height图片尺寸(帮助预渲染布局)推荐

Twitter Card 补充字段

字段含义
twitter:cardsummary / summary_large_image / app / player
twitter:title标题(覆盖 og:title)
twitter:description描述(覆盖 og:description)
twitter:image图片(覆盖 og:image)
twitter:site@站点账号
twitter:creator@作者账号

关键差别og:property=twitter:name=——写反了部分解析器会忽略。

1200×630 由来

Facebook 早期定义卡片为 1.91:1
1.91:1 + 1200px 宽 → 1200×629.3 ≈ 1200×630
Retina 2x 时缩放到 600×315 显示,仍清晰

最低尺寸 600×315,否则 Facebook 拒绝。

各平台显示规则(速查)

平台优先级缓存图片裁剪备注
Facebookog: > 任何30 天1.91:1 完整显示Sharing Debugger 强制刷新
Twitter / Xtwitter: > og:7 天summary_large_image 完整显示改 URL 参数刷新
LinkedInog: only7 天1.91:1 完整显示Post Inspector 刷新
Slackog: only24 小时完整显示不识别 og:image:secure_url
Discordog: only≈1 小时完整显示不支持 SVG
微信 PCog: + 自有解析不公开完整显示移动端规则不一致
iMessageog: only较长1.91:1 + 圆角物理显示宽 ≈280px
WhatsAppog: only较长完整显示强烈依赖 og:image

安全区设计

┌──────────── 1200 ────────────┐
│      安全边距 100px          │ 60
│  ┌────────────────────────┐  │
│  │                        │  │
│  │     主标题文字         │  │ 630
│  │     1000×450 内        │  │
│  │                        │  │
│  └────────────────────────┘  │
│                              │ 60
└──────────────────────────────┘
  • 主标题:60-100px 字号
  • 描述:30-50px
  • 装饰边距:≥60px

调试工具速链

平台工具
Facebookhttps://developers.facebook.com/tools/debug/
LinkedInhttps://www.linkedin.com/post-inspector/
通用预览https://opengraph.dev/
Slack在 Slack 输入 URL 重抓

curl 模拟抓取

curl -A "facebookexternalhit/1.1" -L https://你的页面 | grep -i og:

常见错误清单

  1. ❌ og:image 用相对路径或 // 协议无关——抓取器读不到
  2. ❌ og:image 用 HTTP 不是 HTTPS——iOS / 微信拒绝
  3. ❌ JS 注入 og meta——抓取器不执行 JS,SSR / 预渲染才行
  4. ❌ 图片在 robots.txt 禁止——抓取被 403
  5. ❌ 改了图但平台还显示旧的——平台有缓存,要么强刷要么换 URL
  6. ❌ 图上文字太小——预览缩略图尺寸下文字糊掉
  7. ❌ og:title 和 <title> 重复——浪费描述空间,应该写更营销化的标题
  8. ❌ Twitter 用了 summary 但图是 1.91:1——会被压缩成正方形

自动化生成方案

方案工具适用
构建时生成@vercel/og + Astro Endpoint静态站,页面数 < 1000
构建时生成satori + puppeteer同上,复杂模板
边缘函数Cloudflare Workers / Vercel OG动态参数化
模板手画Figma / Canva 导出少量重要页面

Astro 推荐astro-og-canvasastro-og-image-generator,构建时为每篇 markdown 生成对应 OG 图。

实操流程

  1. 设计 1200×630 模板,标题占位字号定下
  2. 各页面 frontmatter 配 title / description
  3. 构建时为每篇文章生成 OG 图到 /og/<slug>.png
  4. 模板里输出 og: 和 twitter: 系列 meta
  5. 用 Facebook Sharing Debugger 抓一次新页面,确认图能加载
  6. 链接发到自己微信 / Slack 测试,看预览是否符合预期
  7. 更新图后用 URL 参数(?v=2)强制各平台重抓

OG 图是站外曝光的”封面”——优化它的成本远低于优化首屏内容,但点击率提升经常立竿见影。

❓ 常见问题

为什么 OG 图标准是 1200×630?

1.91:1 的比例 + 1200 像素宽是平衡了多端兼容的折中值比例由来:Facebook 早期把"链接卡片"设计成 1.91:1(宽:高),这个比例不是对应任何屏幕,而是 Facebook 内部 UI 设计师选定的。1200×630 = 1.905:1,最接近 1.91。为什么不用 16:9 (1.78:1)?——16:9 卡片在 Feed 流里看起来"太矮",1.91:1 视觉上更舒展。为什么宽 1200 不是更高分辨率?——(a) 历史上 Facebook 推荐过 1200×630,后续 Twitter / LinkedIn / Slack 跟随成事实标准;(b) 太大的图加重抓取成本(很多平台抓 OG 图设了 5MB / 8MB 上限);(c) Retina 屏幕显示时缩放到 600×315 物理像素,1200 已经够 2x 高清。最低尺寸:Facebook 至少要 600×315,再小会被某些客户端拒绝。最佳实践:1200×630 PNG / JPG,文件 < 1MB。

微信、Twitter、LinkedIn、Slack 的链接预览规则有什么差异?

几个核心差异点:(1) 微信——读 og:title / og:description / og:image,但只在 PC 端微信和企业微信完整显示卡片,普通手机微信对外部链接的卡片显示规则不固定(部分场景显示、部分场景只显示链接文本);公众号文章的封面图比例是 2.35:1(封面 1)或 1:1(封面 2),与 OG 图不通用。(2) Twitter——优先读 twitter:card / twitter:image 系列,找不到才回退到 og:twitter:card 类型有 summary(小图正方形)/ summary_large_image(大图 1.91:1),二者图片要求不同。(3) LinkedIn——读 og:title / og:image,但有强缓存(24 小时-7 天),改了图也不会立即生效,要去 Post Inspector 强制刷新。(4) Slack——读 og:image / og:title / og:description,自动展开为 unfurl 卡片;不识别 og:image:secure_url(要用 og:image 加 https URL)。(5) iMessage / WhatsApp——读 og: 系列,对 og:image 尺寸宽容度高。通用做法:og: 系列必填、twitter: 系列补充,图片用 https 绝对 URL。

OG meta 的最小必填集是什么?

最少 4 个og:titleog:descriptionog:imageog:url完整推荐集: ```html <meta property="og:title" content="页面标题" /> <meta property="og:description" content="一句话描述" /> <meta property="og:image" content="https://example.com/og.jpg" /> <meta property="og:image:width" content="1200" /> <meta property="og:image:height" content="630" /> <meta property="og:url" content="https://example.com/page" /> <meta property="og:type" content="website" /> <meta property="og:site_name" content="站点名" /> <meta property="og:locale" content="zh_CN" /> <meta name="twitter:card" content="summary_large_image" /> <meta name="twitter:title" content="..." /> <meta name="twitter:description" content="..." /> <meta name="twitter:image" content="..." /> <meta name="twitter:site" content="@你的账号" /> `` 注意og: 的属性名用 property=(OGP 协议规定),twitter:name=`(Twitter 文档要求)——写错属性名很多解析器会忽略。

为什么 og:image 必须是绝对 URL(带 https)?

抓取器从外部访问,没有当前页面的"上下文"。普通浏览器解析 <img src="/og.jpg"> 会按当前页面 URL 拼接出绝对路径,但 OG 抓取器(Facebook crawler、Twitterbot、Slackbot)从外部抓取页面后单独发起对图片的请求,没有"相对路径基准"——必须给完整 https URL。常见错误:(1) 写了 /og.jpg(相对路径)——抓取器读到后无法解析;(2) 写了 http://...(HTTP 而非 HTTPS)——很多平台(如微信、iOS 默认 ATS)拒绝加载非 HTTPS 资源,OG 图变空白;(3) 写了 protocol-relative //example.com/og.jpg——大多数抓取器识别不了,必须显式 https:调试:用 curl 模拟抓取:curl -A "facebookexternalhit/1.1" https://你的页面 看返回 HTML 中 og:image 是否真的可访问。

OG 图改了为什么平台还显示旧图?怎么强制刷新?

几乎所有平台都对 OG 抓取做了缓存。常见缓存时长:Facebook 30 天、LinkedIn 7 天、Twitter 7 天、Slack 24 小时、微信不公开(推测较长)。刷新工具: - FacebookSharing Debugger → 输入 URL → 点 "Scrape Again" - TwitterCard Validator(已下线,现需通过开发者门户)→ 实际上 Twitter 现在的刷新策略是改 URL 参数(如加 ?v=2) - LinkedInPost Inspector → 输入 URL → Inspect - Slack:在 Slack 中输入 URL,Slack 会重新抓取(小于 24 小时缓存内同一 URL 不会重抓) - 微信:没有官方刷新工具,常用做法是 URL 加版本参数(?v=20260426)让平台视为新链接 应急方案:换 og:image 的 URL(如 og-v2.jpg 或加查询参数 og.jpg?v=2),各平台都视为新图重抓。

OG 图上放文字会被裁掉吗?文字应该多大?

安全区原则:1200×630 的画布,留 60-100 像素边距,核心文字放中央 1000×450 区域。裁剪风险:(1) Twitter 大图卡片保留全图但圆角裁剪边缘 ≈15px;(2) iMessage 链接预览裁成 1.91:1 但显示宽度只有 ≈280px 物理像素,文字小于 60px 会糊;(3) Facebook 移动端有时裁中央 1.91:1 但比例略变;(4) LinkedIn会按 1.91:1 显示但 mobile 上可能被压缩成方形预览。字号建议: - 主标题:60-100px - 副标题 / 描述:30-50px - 站点 / Logo:20-30px 对比度:标题文字与背景对比度至少 4.5:1(WCAG AA),否则在不同设备的不同色温下可能糊掉。测试:把生成的 OG 图缩成 300×157px 缩略图——还能看清主标题就 OK,看不清就放大字号或简化文字。

纯静态站点 / Astro / Next.js 怎么自动生成 OG 图?

两种主流方案:(1) 构建时生成——用 @vercel/og / satori / puppeteer 在构建期为每个页面渲染一张 PNG,路径如 /og/page-slug.png,HTML 里 og:image 引用它。优点:完全静态、CDN 友好;缺点:构建时间随页面数线性增长,1000 页要花几分钟。(2) 请求时动态生成——Vercel / Cloudflare Workers 提供 OG 图边缘函数,URL 如 /api/og?title=xxx,访问时实时合成 SVG → PNG。优点:参数化灵活,新页面零延迟;缺点:需要 Serverless 运行时(纯静态托管不支持)。Astro 项目推荐:用 astro-og-canvas 或自写 Astro Endpoint + satori,构建时生成,托管到任何静态平台。模板设计:固定背景 + 标题(动态文字)+ 站点 logo + 装饰元素——保证视觉一致,比每页手画 OG 图省事。

做了 og:image 但抓取器抓不到,怎么排查?

按这个 checklist 走一遍:(1) HTML 中真有 meta 标签吗?查看页面源码(不是 DevTools 的 Elements 面板,那是 JS 改过的 DOM)——抓取器只读 HTML 不执行 JS,SPA 中通过 JS 注入的 og:meta 不会被抓(除非用 SSR / 预渲染)。(2) og:image URL 直接访问能打开吗?(a) 是不是 https?(b) 文件是不是真存在?(c) 服务器有没有 robots.txt 禁止抓取?(d) CDN 配置了防盗链?(3) 页面本身能被抓吗?检查 robots.txt 是否允许 facebookexternalhit / Twitterbot / Slackbot 等 user-agent;返回 200 而不是 301/302/403/404。(4) 图片尺寸 / 格式合规吗?至少 600×315、< 8MB、JPG/PNG/GIF。(5) 改完后清缓存了吗?平台都有缓存,调试工具刷新后再测试。抓取模拟curl -A "facebookexternalhit/1.1 (+http://www.facebook.com/externalhit_uatext.php)" -L https://你的页面 看返回是否含 og:image。

🃏 打开 OG 卡片预览 OG/Twitter Card 实时预览·Twitter/Facebook/微信/微博·粘 HTML 自动解析·一键生成 meta 代码