satoriでローカル保存したtwemoji (svg)を使う in Astro

とりあえずこれで動く

loadAdditionalAsset の書き方がよく分からなかったのでメモ。Astroで(ビルド時にローカルで一回だけ)動けばいいというコードであり、他の用途でそのまま使うことはできないので注意。

import twemoji from "@twemoji/parser";

export async function runSatori(): Promise<Buffer> {
  const svg = await satori(
    { ... },
    {
      loadAdditionalAsset: async (languageCode, segment) => {
        if (languageCode === "emoji") {
          // segmentの中身は絵文字🐤そのままでは使えないので、コードに変換する
          const entity = twemoji.parse(segment, {
            buildUrl(codepoints, assetType) {
              // 保存した場所のパスに変えてね🐤
              return `src/assets/twemoji/${codepoints}.svg`;
            },
          })[0];

          const svg = readFileSync(entity.url);
          return `data:image/svg+xml;base64,${svg.toString("base64")}`;
        }

        return segment;
      },
    },
  );

  return sharp(Buffer.from(svg)).png().toBuffer();
}

Twemojiは2022年で止まっており更新されないであろうこと、とはいえ自分にとって必要十分な内容を備えていること、どうせ更新されないものを都度fetchするのは時間の無駄であるうえアタックサーフェスを増やすこと… などを考慮して、svg全部をgitリポジトリにコピーして放り込みました。

おわり。