問題提起
前回で、SSRではogp画像の自動生成ができたが、SGではできなかった。
調べて、satoriというsvg生成するパッケージと、sharpというsvgをpngに変換するパッケージで、ogpを自動生成、ついでにそれをブログのサムネイル(アイキャッチを設定していないとき)にした。
コード
import satori from "satori";
import fs from "fs";
import sharp from "sharp";
// import { inter } from "/utils/fonts";
// import { Roboto, Noto_Sans_JP } from "next/font/google";
export default async function writeOgpImage(articleTitle, path) {
if (!fs.existsSync(`public/writePngImg/${path}`))
fs.mkdirSync(`public/writePngImg/${path}`);
const image = await makeImg(articleTitle);
fs.writeFileSync(`public/writePngImg/${path}/ogp.png`, image);
}
const makeImg = async function (title) {
const roboto = fs.readFileSync("./makeImgAssets/Roboto-Regular.ttf");
const notojp = fs.readFileSync("./makeImgAssets/NotoSansJP-Regular.ttf");
const svg = await satori(
<div
style={{
color: "black",
background:
"url(背景画像をmicrocmsに置き、絶対パスで記述しました)",
backgroundSize: "1200px 800px",
backgroundRepeat: "no-repeat",
backgroundPosition: "right top",
display: "flex",
width: "100%",
height: "100%",
padding: "60px 30px",
fontFamily: "Inter",
}}
>
<div
style={{
fontSize: "48px",
background: "rgba(255,255,255,0.8)",
width: "100%",
height: "100%",
padding: "40px 20px",
borderRadius: "8px",
display: "flex",
alignItems: "center",
justifyContent: "center",
wordBreak: "auto-phrase",
position: "relative",
}}
>
{title}
<p
style={{
fontSize: "32px",
position: "absolute",
bottom: "48px",
right: "48px",
display: "flex",
alignItems: "center",
gap: "4px",
}}
>
<img
style={{ display: "block", width: "50px", height: "50px" }}
src="松の画像をmicrocmsに置き、絶対パスで記述しました"
alt=""
/>
松竹梅
</p>
</div>
</div>,
{
width: 1200,
height: 800,
// embedFont: false,
fonts: [
{
name: "robot",
data: roboto,
},
{
name: "NotoSansJP",
data: notojp,
},
],
}
);
return sharp(Buffer.from(svg)).png().toBuffer();
};
上記を下記のようにgenerateStaticParams内で関数としていれると、開発環境で保存したらその時点で画像がフォルダに格納される。サムネやogpはそれを読み込むだけ
export async function generateStaticParams() {
const allTitleSlugs = await getAllTitleAndSlugs();
for (let i = 0; i < allTitleSlugs.length; i++) {
await writeOgpImage(allTitleSlugs[i].title, allTitleSlugs[i].slug);
}
・・・・
return paths;
}
次はコードを見やすくするhighlightの導入