在previous blog post中,我提到我正在使用Next.js项目来运行@vercel/og
逻辑来生成我的OG:我的博客文章的图像。
现在不再需要这一点,我想出了如何在我的Astro博客项目(此网站; - )中运行此操作。
为此需要进行一些更改。
我的下一个项目中的原始代码看起来像这样:
// /pages/api/og.jsx
import { ImageResponse } from '@vercel/og';
export const config = {
runtime: 'experimental-edge',
};
const font = fetch(new URL('../../assets/Inter.ttf', import.meta.url)).then(
res => res.arrayBuffer()
);
export default async function handler(req) {
const fontData = await font;
try {
const { searchParams } = new URL(req.url);
// ?title=<title>
const hasTitle = searchParams.has('title');
const title = hasTitle
? searchParams.get('title')?.slice(0, 200)
: 'My default title';
return new ImageResponse(
(
<div
style={{
background: 'white',
width: '100%',
height: '100%',
display: 'flex',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
fontFamily: 'Inter',
backgroundImage:
'radial-gradient(circle at 25px 25px, lightgray 2%, transparent 0%), radial-gradient(circle at 75px 75px, lightgray 2%, transparent 0%)',
backgroundSize: '100px 100px',
}}
>
<div
style={{
width: '80%',
display: 'flex',
flexDirection: 'column',
textAlign: 'center',
alignItems: 'center',
}}
>
<p style={{ fontSize: 32 }}>Thomas Ledoux's blog</p>
<p style={{ fontSize: 64 }}>{title}</p>
</div>
</div>
),
{
width: 1200,
height: 600,
fonts: [
{
name: 'Inter',
data: fontData,
style: 'normal',
},
],
}
);
} catch (e) {
console.log(`${e.message}`);
return new Response(`Failed to generate the image`, {
status: 500,
});
}
}
如您所见,JSX代码被用于构建我的OG:Image。
在Next内部的/api
文件夹中使用JSX代码在Next.js Projects部署到Vercel。
在部署到Vercel(例如Astro)的其他框架上,这是not possible。
尝试此操作时,我会收到以下错误消息:vc-file-system:api/og.js:25:8: ERROR: The JSX syntax extension is not currently enabled
。
所以我必须在API函数内使用JSX解决方法。
幸运的是,ImageResponse
函数还允许使用"React-elements-like" objects。
使用上面链接上提供的示例,我在Astro Project内部创建了以下边缘API路由:
// /api/og.js
import { ImageResponse } from '@vercel/og';
export const config = {
runtime: 'experimental-edge',
};
const font = fetch(new URL('../assets/Inter.ttf', import.meta.url)).then(res =>
res.arrayBuffer()
);
export default async function handler(req) {
const fontData = await font;
try {
const { searchParams } = new URL(req.url);
// ?title=<title>
const hasTitle = searchParams.has('title');
const title = hasTitle
? searchParams.get('title')?.slice(0, 200)
: 'My default title';
const html = {
type: 'div',
props: {
children: [
{
type: 'div',
props: {
style: {
width: '80%',
display: 'flex',
flexDirection: 'column',
textAlign: 'center',
alignItems: 'center',
},
children: [
{
type: 'p',
props: {
style: { fontSize: 32 },
children: 'Blog by Thomas Ledoux',
},
},
{
type: 'p',
props: {
style: { fontSize: 64 },
children: title,
},
},
],
},
},
],
style: {
background: 'white',
width: '100%',
height: '100%',
display: 'flex',
textAlign: 'center',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
fontFamily: 'Inter',
backgroundImage:
'radial-gradient(circle at 25px 25px, lightgray 2%, transparent 0%), radial-gradient(circle at 75px 75px, lightgray 2%, transparent 0%)',
backgroundSize: '100px 100px',
},
},
};
return new ImageResponse(html, {
width: 1200,
height: 600,
fonts: [
{
name: 'Inter',
data: fontData,
style: 'normal',
},
],
});
} catch (e) {
console.log(`${e.message}`);
return new Response(`Failed to generate the image`, {
status: 500,
});
}
}
现在,我希望API路线被Vercel捡起。
默认情况下,Astro Build命令将不会在根目录中选择这些API路由(因为它们是(vercel build命令)[https://github.com/withastro/astro/issues/5451#issuecomment-1339720682])的一部分。
因此,为了在用例中使用此功能,我切换到使用(vercel cli)[https://vercel.com/docs/cli]来构建和部署我的项目。
使用npm i -g vercel
全球安装CLI后,我可以运行vercel build
在本地构建我的项目,然后运行vercel deploy --prebuilt
以直接部署本地创建的构建构建。
我还选择禁用推送到我的git存储库的自动部署,因为我现在通过CLI进行部署。
禁用自动部署是通过在根目录中添加vercel.json
文件完成的,其中包含以下内容:
{
"git": {
"deploymentEnabled": false
}
}
希望这可以帮助其他想要在其Astro项目中使用无服务器/边缘API功能的人。
可以找到源代码here。