/* eslint-disable @next/next/no-img-element */ import { readFile } from "node:fs/promises"; import { join } from "node:path"; import { ImageResponse } from "next/og"; export const ogImageSize = { width: 1222, height: 560 } as const; export const ogImageContentType = "image/png"; let bannerDataPromise: Promise | undefined; let fontDataPromise: Promise | undefined; function shorten(value: string, length: number): string { const normalized = value.replace(/\s+/gu, " ").trim(); return normalized.length > length ? `${normalized.slice(0, length - 1).trimEnd()}…` : normalized; } function getBannerData(): Promise { bannerDataPromise ??= readFile( join(process.cwd(), "public/web_banner.png"), "base64", ).then((data) => `data:image/png;base64,${data}`); return bannerDataPromise; } function getFontData(): Promise { fontDataPromise ??= readFile(join(process.cwd(), "public/Kanit-SemiBold.ttf")); return fontDataPromise; } export async function generateOgImage({ title, sub, }: { title: string; sub: string; }) { const [bannerSrc, kanit] = await Promise.all([getBannerData(), getFontData()]); return new ImageResponse(
Banner
{shorten(title, 24)}
{shorten(sub, 92)}
, { ...ogImageSize, fonts: [{ name: "Kanit", data: kanit, style: "normal", weight: 600 }], }, ); }