2023.02.05
これまでは、メイン画像をFigmaで作成してmicroCSM側に記事と一緒に登録しており記事のメイン画像&OGP画像として使用するような仕組みにしていました。
問題点としては毎回メイン画像を作成する手間とメインとOGP画像に別々の画像を指定できないことです。
色々なデザインの画像を作成することが出来るのは良いのですが、その分簡単な記事などを書くときは少し手間に感じていました...
そこでメイン画像とOGP画像を切り分けることにしました。
(メイン画像に好きな画像を差し込めるようになるのでもっと早く導入すべきでした...w)
OG Image Generation はVercel Edge Functions を使用したOG画像の生成に関しての題材があります。
Edge Functionsは簡単にいうとVercelがもつCDNのエッジにて簡単な処理を実行することができる機能です。
https://og-playground.vercel.app/ で簡単に確認できるので一度見てみて下さい。
OG Imageの生成には「satori」とResvgでHTML, CSSをPNGに変換している。
参考のサンプルも記載があるので下記から確認してみて下さい。
https://vercel.com/docs/concepts/functions/edge-functions/og-image-examples
このブログにはChakraUIを使用しているので導入したかったのですが少し手間がかかりそうだったので断念。
configの設定で runtime: 'experimental-edge' を有効にするのをお忘れなく。
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 hasTitle = searchParams.has('title')
const title = hasTitle
? searchParams.get('title')?.slice(0, 100)
: 'megumu.me'
return new ImageResponse(
(
<div
style={{
display: 'flex',
justifyContent: 'center',
height: '100%',
width: '100%',
alignItems: 'center',
background: 'linear-gradient(135deg, #6139FD, #974FFE, #C260FE)'
}}
>
<div
style={{
backgroundColor: 'white',
border: 'none',
height: '84%',
width: '88%',
display: 'flex',
textAlign: 'left',
alignItems: 'center',
justifyContent: 'center',
flexDirection: 'column',
flexWrap: 'nowrap',
padding: 40,
position: 'relative',
borderRadius: 50
}}
>
<div
style={{
fontSize: 54,
color: 'black',
lineHeight: 1.3,
width: '100%'
}}
>
{title}
</div>
<div
style={{
display: 'flex',
gap: 8,
alignItems: 'center',
position: 'absolute',
bottom: 20,
right: 40
}}
>
<div
style={{
width: '40px',
height: '40px',
borderRadius: '50%',
background:
'linear-gradient(135deg, #6139FD, #974FFE, #C260FE)'
}}
></div>
<p style={{ fontSize: 34, marginTop: 10 }}>megumu.me</p>
</div>
</div>
</div>
),
{
width: 1280,
height: 640
}
)
} catch (e: any) {
console.log(`${e.message}`)
return new Response(`Failed to generate the image`, {
status: 500
})
}
}