Some checks failed
Build & Deploy / 🚀 Deploy (push) Has been skipped
Build & Deploy / 🏗️ Build (push) Failing after 8m32s
Build & Deploy / 🔍 Prepare (push) Successful in 18s
Build & Deploy / 🧪 QA (push) Failing after 1m33s
Build & Deploy / 🩺 Health Check (push) Has been skipped
Build & Deploy / 🔔 Notify (push) Successful in 1s
71 lines
2.2 KiB
TypeScript
71 lines
2.2 KiB
TypeScript
import { ImageResponse } from "next/og";
|
|
import { getAllPosts } from "../../../../src/lib/posts";
|
|
import { blogThumbnails } from "../../../../src/components/blog/blogThumbnails";
|
|
import { BlogOGImageTemplate } from "../../../../src/components/BlogOGImageTemplate";
|
|
import { getOgFonts, OG_IMAGE_SIZE } from "../../../../src/lib/og-helper";
|
|
import * as fs from "node:fs/promises";
|
|
import * as path from "node:path";
|
|
|
|
export const size = OG_IMAGE_SIZE;
|
|
export const contentType = "image/png";
|
|
export const runtime = "nodejs";
|
|
|
|
export default async function Image({
|
|
params,
|
|
}: {
|
|
params: Promise<{ slug: string }>;
|
|
}) {
|
|
const { slug } = await params;
|
|
const allPosts = await getAllPosts();
|
|
const post = allPosts.find((p) => p.slug === slug);
|
|
|
|
let backgroundImageSrc: string | undefined = undefined;
|
|
|
|
// If we have a custom generated thumbnail, convert it to a data URI for Satori
|
|
if (post?.thumbnail) {
|
|
try {
|
|
const filePath = path.join(process.cwd(), "public", post.thumbnail);
|
|
const fileBuffer = await fs.readFile(filePath);
|
|
|
|
const ext = path.extname(post.thumbnail).substring(1).toLowerCase();
|
|
const mimeType =
|
|
ext === "jpg" || ext === "jpeg" ? "image/jpeg" : "image/png";
|
|
|
|
backgroundImageSrc = `data:${mimeType};base64,${fileBuffer.toString("base64")}`;
|
|
} catch (err) {
|
|
console.warn(
|
|
`[OG Image Generator] Could not read thumbnail file for ${slug} to use as background:`,
|
|
err,
|
|
);
|
|
// Fall through to standard plain background
|
|
}
|
|
}
|
|
|
|
const thumbnail = blogThumbnails[slug];
|
|
|
|
const title = post?.title || "Marc Mintel";
|
|
const description =
|
|
post?.description ||
|
|
"Technical problem solver's blog - practical insights and learning notes";
|
|
const label = post ? "Blog Post" : "Engineering";
|
|
const accentColor = thumbnail?.accent;
|
|
const keyword = thumbnail?.keyword;
|
|
|
|
const fonts = await getOgFonts();
|
|
|
|
return new ImageResponse(
|
|
<BlogOGImageTemplate
|
|
title={title}
|
|
description={description}
|
|
label={label}
|
|
accentColor={accentColor}
|
|
keyword={keyword}
|
|
backgroundImageSrc={backgroundImageSrc}
|
|
/>,
|
|
{
|
|
...OG_IMAGE_SIZE,
|
|
fonts: fonts as any,
|
|
},
|
|
);
|
|
}
|