通过一次 API 调用生成 Open Graph 图像,无需 Next.js
使用 botoi OG 图像 API 从任何框架生成 1200x630 PNG 社交卡。 适用于 Astro、Django、Rails、Laravel 和无头 CMS 平台。
您的博客文章会在 Twitter 上分享。 该链接不是带有标题卡的丰富预览,而是显示 空白的灰色框。 或者更糟糕的是,图标被拉伸。 每次没有正确的 OG 图片的分享都是一次错过的点击。
流行的解决方案是 Vercel 的 @vercel/og 图书馆。 效果很好,但是被锁定了
Next.js 和 Vercel 的基础设施。 Satori(其背后的引擎)需要一个具有特定功能的 Node.js 运行时
字体加载功能。 如果您使用 Astro、Django、Rails、Laravel、Hugo 或任何其他语言进行构建
框架,你就靠你自己了。
有一种更简单的方法:向 API 发送一个 POST 请求并获取完成的 1200x630 PNG。 没有 Node.js 依赖。 没有框架锁定。 无需维护图像渲染管道。
一个 POST 请求,一个 PNG 返回
这 botoi 和图像 API 接受包含您的标题、描述和主题首选项的 JSON 正文。 它返回原始 PNG 二进制数据。
curl -X POST https://api.botoi.com/v1/og/generate \\
-H "Content-Type: application/json" \\
-d '{
"title": "How to build a REST API in Go",
"description": "A step-by-step guide with net/http and no frameworks",
"theme": "dark"
}' \\
--output og-image.png
就是这样。 响应是一个 PNG 文件,您可以保存、提供或上传到 CDN:
HTTP/1.1 200 OK
Content-Type: image/png
Content-Length: 48271
(binary PNG data, 1200x630px)
API 处理排版、布局和适当的大小调整。 你传入文本,就得到图像。
Astro 集成:在构建时生成 OG 图像
Astro 的静态站点生成使其特别干净。 创建一个动态 API 路由来获取
构建期间的 OG 图像并将其作为静态图像 .png 文件。
// src/pages/og/[slug].png.ts
import type { APIRoute, GetStaticPaths } from 'astro';
// Your posts data source (markdown, CMS, database, etc.)
import { getAllPosts } from '@/lib/posts';
export const getStaticPaths: GetStaticPaths = async () => {
const posts = await getAllPosts();
return posts.map((post) => ({
params: { slug: post.slug },
props: { title: post.title, description: post.description },
}));
};
export const GET: APIRoute = async ({ props }) => {
const res = await fetch('https://api.botoi.com/v1/og/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: props.title,
description: props.description,
theme: 'dark',
}),
});
const imageBuffer = await res.arrayBuffer();
return new Response(imageBuffer, {
headers: {
'Content-Type': 'image/png',
'Cache-Control': 'public, max-age=31536000, immutable',
},
});
};
期间 astro build,此路线为每个帖子生成一个 PNG。 输出文件落在
你的 dist/og/ 目录作为静态资产。 没有运行时图像生成,没有无服务器
功能,无冷启动。
引用页面标题中的图像:
<!-- In your BaseLayout.astro or page head -->
<meta property="og:image" content={\`https://yoursite.com/og/\${slug}.png\`} />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content={\`https://yoursite.com/og/\${slug}.png\`} />
每个页面都有一张独特的社交卡,在构建过程中生成一次并由 CDN 永久缓存。
Django 和 Rails 集成
服务器渲染框架可以按需生成 OG 图像并缓存结果。
姜戈
# views.py
import requests
from django.http import HttpResponse
from django.views.decorators.cache import cache_page
@cache_page(60 * 60 * 24) # Cache for 24 hours
def og_image(request, slug):
post = get_object_or_404(Post, slug=slug)
response = requests.post(
'https://api.botoi.com/v1/og/generate',
json={
'title': post.title,
'description': post.description,
'theme': 'dark',
},
timeout=5,
)
return HttpResponse(
response.content,
content_type='image/png',
)
# urls.py
urlpatterns = [
path('og/<slug:slug>.png', views.og_image, name='og_image'),
]
这 @cache_page 装饰器将生成的图像存储24小时。 第一个之后
请求时,Django 直接提供缓存的 PNG,而无需再次访问 API。
导轨
# app/controllers/og_images_controller.rb
class OgImagesController < ApplicationController
def show
post = Post.find_by!(slug: params[:slug])
response = HTTP.post(
'https://api.botoi.com/v1/og/generate',
json: {
title: post.title,
description: post.description,
theme: 'dark'
}
)
expires_in 24.hours, public: true
send_data response.body.to_s, type: 'image/png', disposition: 'inline'
end
end
# config/routes.rb
get 'og/:slug.png', to: 'og_images#show'
这两个示例都遵循相同的模式:通过 slug 查找帖子,发布标题和描述 到 API,并返回带有缓存标头的 PNG。 框架处理缓存; API 句柄 图像生成。
Headless CMS 集成:发布时生成
如果您的内容位于 Strapi、Contentful 或 Sanity 等无头 CMS 中,您可以生成 OG 每当编辑发布或更新帖子时都会显示图像。 连接在内容上触发的 Webhook 变化。
通用 Webhook 处理程序
// Webhook handler (any Node.js server or serverless function)
import { writeFileSync } from 'fs';
export async function handleCmsPublish(payload) {
const { title, description, slug } = payload.entry;
const res = await fetch('https://api.botoi.com/v1/og/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ title, description, theme: 'light' }),
});
const buffer = Buffer.from(await res.arrayBuffer());
// Save to your public/static directory or upload to S3/R2
writeFileSync(\`./public/og/\${slug}.png\`, buffer);
console.log(\`Generated OG image for: \${slug}\`);
}
Strapi 生命周期挂钩
// Strapi lifecycle hook: src/api/post/content-types/post/lifecycles.js
module.exports = {
async afterUpdate(event) {
const { result } = event;
const res = await fetch('https://api.botoi.com/v1/og/generate', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
title: result.title,
description: result.description,
theme: 'dark',
}),
});
// Upload to your CDN or save locally
const buffer = Buffer.from(await res.arrayBuffer());
await strapi.plugins.upload.services.upload.upload({
data: { path: \`og/\${result.slug}.png\` },
files: { buffer, name: \`\${result.slug}.png\`, type: 'image/png' },
});
},
};
此方法对于内容编辑者通过 CMS 发布而开发人员不通过 CMS 发布的团队非常有用 想要为每个文本更改运行构建管道。 当 OG 图像自动重新生成时 帖子标题或描述更改。
奖励:从任何 URL 中提取 OG 元数据
botoi API 还提供 /v1/url-metadata,它的作用相反:给定一个 URL,它会获取
该页面并提取其开放图谱标签。 这对于构建链接预览、社交卡很有用
验证器或 SEO 审核工具。
curl -X POST https://api.botoi.com/v1/url-metadata \\
-H "Content-Type: application/json" \\
-d '{"url": "https://github.com/astro-community/astro-embed"}'
回复:
{
"success": true,
"data": {
"url": "https://github.com/astro-community/astro-embed",
"status": 200,
"title": "GitHub - astro-community/astro-embed",
"description": "Components to embed third-party media in Astro projects",
"og": {
"title": "astro-embed",
"description": "Components to embed third-party media in Astro projects",
"image": "https://opengraph.githubassets.com/...",
"type": "object",
"url": "https://github.com/astro-community/astro-embed",
"site_name": "GitHub"
}
}
}
使用它在您的应用程序中构建链接预览组件:
async function getLinkPreview(url: string) {
const res = await fetch('https://api.botoi.com/v1/url-metadata', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({ url }),
});
const { data } = await res.json();
return {
title: data.og?.title ?? data.title,
description: data.og?.description ?? data.description,
image: data.og?.image,
siteName: data.og?.site_name,
};
}
合并两个端点:使用 /v1/url-metadata 检查您的页面在社交媒体上的显示方式
平台,以及 /v1/og/generate 创建使它们看起来不错的图像。
为什么不自己经营 Satori?
你可以。 Satori 是开源的并产生高质量的输出。 但自己运行意味着:
- 安装和捆绑自定义字体(Satori 不使用系统字体)
- 设置 Node.js 运行时或 Edge Function 以进行图像渲染
- 编写 JSX-to-SVG 模板并使用 resvg 将 SVG 转换为 PNG
- 渲染大图像时处理无服务器平台上的内存限制
- 随着 Satori API 的发展维护管道
API 调用将所有这些替换为单个 HTTP 请求。 如果您的 OG 图像需求是 简单明了(标题 + 描述 + 品牌),API 方法节省了设置时间和 ongoing maintenance.
FAQ
- 生成的 OG 图像的尺寸是多少?
- 每张图像均为 1200x630 像素,这是 Facebook、Twitter/X、LinkedIn 和 Slack 推荐的标准 Open Graph 图像大小。 输出是 PNG 文件。
- 我需要 API 密钥吗?
- 不需要。免费套餐每分钟允许 5 个请求,无需 API 密钥。 对于构建在每个页面视图上生成图像的管道或高流量站点,请从 botoi API 文档页面获取密钥以解锁更高的速率限制。
- 我可以自定义字体、颜色或布局吗?
- theme 参数接受“light”或“dark”来控制整体配色方案。 API 根据您的标题和描述长度自动处理排版和布局。 对于完全自定义设计,请使用 API 生成基础图像,并使用您自己的叠加逻辑对其进行后处理。
- 图像生成速度有多快?
- 该 API 在边缘的 Cloudflare Workers 上运行。 大多数请求会在 500 毫秒内返回完成的 PNG。 如果缓存结果(建议用于静态站点),则每个标题、描述和主题的唯一组合仅生成一次。
- /v1/url-metadata 端点有什么作用?
- 将 URL 发布到 /v1/url-metadata,API 会获取该页面,解析其 HTML,并返回结构化开放图谱元数据:og:title、og:description、og:image、og:type 和 Twitter Card 标签。 使用它可以预览在社交媒体上共享时任何 URL 的显示方式,或者将元数据提取到您自己的链接预览中。
开始使用 botoi 构建
150+ 个 API 端点,涵盖查询、文本处理、图片生成和开发者工具。免费套餐,无需信用卡。