新しい個人ブログにお引越ししたはいいものの、永遠に工事中のままになっているのをどうにかする記事第1弾です。
これからは備忘録とか雑に書いていきたいと思ってます。マジで。
Deno。2.0 がリリースされてから積極的に使い始めましたがかなりお気に入りです。
Node.js はちょっと書くのですら ESM, CommonJS, TypeScript で設定が絡み合うので、そこから解放されるのはめっちゃいいです。 フォーマッター、リンターもツールチェインに含まれていてそのまま使えるのも神ですし、Node-API も使えますし、設定なしで実行できるの最高です。
そんな Deno でこのサイトの OGP 画像を自動生成してみました。
使うのは
@vercel/og というライブラリです。
ImageResponse
に JSX をぶん投げるだけで画像が返ってきます。
そういえば tsx が使えるのもいいですね。 https://docs.deno.com/runtime/reference/jsx/
import { ImageResponse } from "npm:@vercel/[email protected]";
const image = await new ImageResponse(
(
<div
style={{
width: '100%',
height: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
fontSize: 128,
background: 'lavender',
}}
>
Hello!
</div>
)
)
埋め込むタイトルは Front Matter 部分に記述しているので、そこから取得しています。形式は TOML なので、 @std/toml を使います。 雑にパースして zod でバリデーションします。
import { parse as parseToml } from "jsr:@std/[email protected]";
import { z } from "npm:[email protected]";
const content: string = "";
const match = content.match(/\+\+\+\n([\s\S]*?)\n\+\+\+/);
if (!match) throw new Error("FrontMatterが見つかりません");
const parsedContent = parseToml(match[1]);
const schema = z.object({
title: z.string(),
});
const title = schema.parse(parsedContent).title;
あとは Cursor にいい感じで!ってお願いしたら好みのが出てきていい。ちなみにあまみゃのイメージカラーを渡しています(#C5EDFF)。
生成とは関係ないですが、Hugo(Blowfish) は OGP 画像を入れるとリストページにも表示される仕様だったので、テンプレートをいじって画像を消したりもしました。
こうして OGP がちゃんと出るようになったと。
やっぱり1ファイルで依存も全部描ける Deno 天才だな。