feat(og): migrate to co-located opengraph-image.tsx convention

This commit is contained in:
2026-02-17 11:57:46 +01:00
parent e2c9ec507f
commit 28053952ea
7 changed files with 143 additions and 72 deletions

View File

@@ -0,0 +1,23 @@
import { ImageResponse } from "next/og";
import { OGImageTemplate } from "../../src/components/OGImageTemplate";
import { getOgFonts, OG_IMAGE_SIZE } from "../../src/lib/og-helper";
export const size = OG_IMAGE_SIZE;
export const contentType = "image/png";
export const runtime = "nodejs";
export default async function Image() {
const fonts = await getOgFonts();
return new ImageResponse(
<OGImageTemplate
title="Über mich."
description="15 Jahre Erfahrung. Ein Ziel: Websites, die ihre Versprechen halten."
label="Marc Mintel"
/>,
{
...OG_IMAGE_SIZE,
fonts: fonts as any,
},
);
}

View File

@@ -1,54 +0,0 @@
import { ImageResponse } from "next/og";
import { blogPosts } from "../../../../src/data/blogPosts";
import { blogThumbnails } from "../../../../src/data/blogThumbnails";
import { OGImageTemplate } from "../../../../src/components/OGImageTemplate";
import { getOgFonts, OG_IMAGE_SIZE } from "../../../../src/lib/og-helper";
export const runtime = "nodejs";
export async function GET(
request: Request,
{ params }: { params: Promise<{ slug?: string[] }> },
) {
const { slug: slugArray } = await params;
const slug = slugArray?.[0] || "home";
let title: string;
let description: string;
let label: string | undefined;
let accentColor: string | undefined;
let keyword: string | undefined;
if (slug === "home") {
title = "Marc Mintel";
description =
"Technical problem solver's blog - practical insights and learning notes";
label = "Engineering";
} else {
const post = blogPosts.find((p) => p.slug === slug);
const thumbnail = blogThumbnails[slug];
title = post?.title || "Marc Mintel";
description =
post?.description ||
"Technical problem solver's blog - practical insights and learning notes";
label = post ? "Blog Post" : "Engineering";
accentColor = thumbnail?.accent;
keyword = thumbnail?.keyword;
}
const fonts = await getOgFonts();
return new ImageResponse(
<OGImageTemplate
title={title}
description={description}
label={label}
accentColor={accentColor}
keyword={keyword}
/>,
{
...OG_IMAGE_SIZE,
fonts: fonts as any,
},
);
}

View File

@@ -0,0 +1,43 @@
import { ImageResponse } from "next/og";
import { blogPosts } from "../../../src/data/blogPosts";
import { blogThumbnails } from "../../../src/data/blogThumbnails";
import { OGImageTemplate } from "../../../src/components/OGImageTemplate";
import { getOgFonts, OG_IMAGE_SIZE } from "../../../src/lib/og-helper";
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 post = blogPosts.find((p) => p.slug === slug);
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(
<OGImageTemplate
title={title}
description={description}
label={label}
accentColor={accentColor}
keyword={keyword}
/>,
{
...OG_IMAGE_SIZE,
fonts: fonts as any,
},
);
}

View File

@@ -33,20 +33,11 @@ export async function generateMetadata({
title: post.title,
description: post.description,
type: "article",
images: [
{
url: `/api/og/${slug}`,
width: 1200,
height: 630,
alt: post.title,
},
],
},
twitter: {
card: "summary_large_image",
title: post.title,
description: post.description,
images: [`/api/og/${slug}`],
},
};
}

View File

@@ -0,0 +1,23 @@
import { ImageResponse } from "next/og";
import { OGImageTemplate } from "../../src/components/OGImageTemplate";
import { getOgFonts, OG_IMAGE_SIZE } from "../../src/lib/og-helper";
export const size = OG_IMAGE_SIZE;
export const contentType = "image/png";
export const runtime = "nodejs";
export default async function Image() {
const fonts = await getOgFonts();
return new ImageResponse(
<OGImageTemplate
title="Kontakt."
description="Bereit für eine Zusammenarbeit? Lassen Sie uns gemeinsam etwas bauen, das wirklich funktioniert."
label="Get in touch"
/>,
{
...OG_IMAGE_SIZE,
fonts: fonts as any,
},
);
}

View File

@@ -0,0 +1,23 @@
import { ImageResponse } from "next/og";
import { OGImageTemplate } from "../src/components/OGImageTemplate";
import { getOgFonts, OG_IMAGE_SIZE } from "../src/lib/og-helper";
export const size = OG_IMAGE_SIZE;
export const contentType = "image/png";
export const runtime = "nodejs";
export default async function Image() {
const fonts = await getOgFonts();
return new ImageResponse(
<OGImageTemplate
title="Marc Mintel"
description="Technical problem solver's blog - practical insights and learning notes"
label="Engineering"
/>,
{
...OG_IMAGE_SIZE,
fonts: fonts as any,
},
);
}

View File

@@ -6,14 +6,36 @@ import { join } from "path";
* Since we are using runtime = 'nodejs', we can read them from the filesystem.
*/
export async function getOgFonts() {
const boldFontPath = join(
process.cwd(),
"apps/web/public/fonts/Inter-Bold.woff",
);
const regularFontPath = join(
process.cwd(),
"apps/web/public/fonts/Inter-Regular.woff",
);
// Use relative path from process.cwd() which usually is the monorepo root or apps/web
// We try both to be safe during different execution contexts (dev vs build vs runtime)
const pathsToTry = [
join(process.cwd(), "apps/web/public/fonts"),
join(process.cwd(), "public/fonts"),
];
let boldFontPath = "";
let regularFontPath = "";
for (const basePath of pathsToTry) {
const b = join(basePath, "Inter-Bold.woff");
const r = join(basePath, "Inter-Regular.woff");
try {
if (readFileSync(b) && readFileSync(r)) {
boldFontPath = b;
regularFontPath = r;
break;
}
} catch (e) {
continue;
}
}
if (!boldFontPath || !regularFontPath) {
console.error(
`[OG] Could not find fonts in either ${pathsToTry.join(" or ")}`,
);
return [];
}
try {
console.log(
@@ -40,7 +62,7 @@ export async function getOgFonts() {
},
];
} catch (error) {
console.error(`[OG] Failed to load fonts from ${process.cwd()}:`, error);
console.error(`[OG] Failed to load fonts:`, error);
return [];
}
}