メインコンテンツへスキップ

個人ブログのOGP画像をDenoで自動生成してみる

·697 文字·2 分
Development Deno

新しい個人ブログにお引越ししたはいいものの、永遠に工事中のままになっているのをどうにかする記事第1弾です。

これからは備忘録とか雑に書いていきたいと思ってます。マジで。


Deno。2.0 がリリースされてから積極的に使い始めましたがかなりお気に入りです。

https://deno.com/blog/v2.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 天才だな。

Taiyo Minagawa (sun-yryr)
著者
Taiyo Minagawa (sun-yryr)