Vercel/og 是?
@vercel/og Vercel宣布可以在边缘动态生成 OG 图像。
什么意思呢?
我最近在项目里遇到一个需求,因为项目在澳大利亚上线的关系,每隔一段时间要过一次审查,每次审查需要对OG image进行修改文言,每次都要让前端进行修改,后来我们就在思考:
有没有什么办法?可以一劳永逸的自动更新图片呢?
这就是我们本次要介绍的vercel og的作用了。他是Vercel推出的一个根据Vercel Edge Functions动态生成 OG 图像的工具:
由于 OG 图像可以使用 HTML 和 CSS(或者更确切地说,JSX或TSX)来定义,因此定义 OG 图像非常容易,特别是对于 React 工程师来说,这个效率是惊人的。
核心引擎使用一个名为Satori的库,它将 HTML 和 CSS 转换为 SVG来供使用。
环境
- nextjs
- Vercel Edge Functions
- @Vercel/og
尝试
实现非常简单,runtime: 'experimental-edge'
只需在 API 路由中创建一个端点即可。
nextjs的路由里有一个api的文件夹:
pages/api/og.tsx
import { ImageResponse } from '@vercel/og'
export const config = {
runtime: 'experimental-edge',
}
export default function handler() {
return new ImageResponse(
(
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
backgroundColor: 'white',
fontSize: '128px',
}}
>
Hello world!
</div>
)
)
}
接下来启动服务器即可,我们就可以在localhost:3000/api/og访问到我们想要看到的图片了。
我们接下来要做的就是把他放到我们需要释放的地方,比如meta标签里,再比如Next的SEO组件里,根据实际需求来做:
import Head from 'next/head'
<Head>
<title>Hello world</title>
<meta
key="og:image"
property="og:image"
content="https://example.com/api/og"
/>
</Head>
动态插入标题
https://example.com/api/og?title=hoge
您可以使用查询参数动态插入标题,如下所示
import { ImageResponse } from '@vercel/og'
import { NextRequest } from 'next/server'
export const config = {
runtime: 'experimental-edge',
}
export default function handler(req: NextRequest) {
try {
const { searchParams } = new URL(req.url)
const title = searchParams.get('title')?.slice(0, 100) ?? 'Hello world!'
return new ImageResponse(
(
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
backgroundColor: 'white',
fontSize: '128px',
}}
>
{/* 这里应该就是hoge */}
{title}
</div>
)
)
} catch (e) {
if (e instanceof Error) {
console.error(e.message)
}
return new Response(`Failed to generate the image`, {
status: 500,
})
}
}
使用字体
根据我的实际操作,OG这个库本身只支持一个字体和粗细大小,其他的类型的字体需要我们手动导入,所以这边详细的阐述一下,导入字体的操作。
除了Google Fonts
之外,还支持ttf
、otf
、woff
等格式的字体文件。
比如我想要导入Arial的字体。
import { ImageResponse } from '@vercel/og'
export const config = {
runtime: 'experimental-edge',
}
export default async function handler() {
const fontData = await fetch(
new URL('../../assets/Arial.ttf', import.meta.url)
).then((res) => res.arrayBuffer())
return new ImageResponse(
(
<div
style={{
display: 'flex',
justifyContent: 'center',
alignItems: 'center',
width: '100%',
height: '100%',
backgroundColor: 'white',
fontFamily: '"Roboto"',
fontWeight: 'bold',
fontSize: '128px',
}}
>
Hello world!
</div>
),
{
fonts: [
{
name: 'Roboto',
data: fontData,
weight: 700,
style: 'normal',
},
],
}
)
}
这样一来就可以达到我们想要的效果了。
总结
这是我第一次尝试并且应用@vercel/og。
我很惊讶使用 Vercel + Edge Functions + Next.js的组合可以如此轻松地动态生成 OG 图像
如果你想使用 Node.js 而不是 Edge,似乎你可以直接使用Satori,我认为它将来会变得更流行。
另外,还请查看官方文档,其中包含使用示例和 API 规范:
Open Graph (OG) Image Generation Image Generation")