feat(site): serve branded OG images dynamically (#1345)

Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
Darius Cepulis
2026-04-15 11:49:35 -05:00
committed by GitHub
co-authored by Claude Opus 4.6
parent 521774a95b
commit 961766d81d
20 changed files with 801 additions and 95 deletions
+2 -2
View File
@@ -7,7 +7,7 @@ import BlogPagination from '@/components/blog/BlogPagination.astro';
import BlogPostCard from '@/components/blog/BlogPostCard.astro';
import FooterEasterEgg from '@/components/FooterEasterEgg.astro';
import JsonLd from '@/components/JsonLd.astro';
import { PRODUCTION_URL } from '@/consts';
import { BLOG_PAGE_SIZE, PRODUCTION_URL } from '@/consts';
import Blog from '@/layouts/Blog.astro';
import { createBlogCollectionSchema } from '@/utils/jsonLd/schemas';
@@ -24,7 +24,7 @@ export const getStaticPaths = (async ({ paginate }) => {
}))
);
return paginate(postsWithAuthors, { pageSize: 10 });
return paginate(postsWithAuthors, { pageSize: BLOG_PAGE_SIZE });
}) satisfies GetStaticPaths;
type PostWithAuthors = CollectionEntry<'blog'> & {
+45
View File
@@ -0,0 +1,45 @@
import type { APIRoute } from 'astro';
import { renderOgImage } from '@/utils/og/render-og-image';
import { getOgCacheHeaders, resolveOgRequest } from '@/utils/og/resolve-og-request';
export const prerender = false;
const imagePromiseCache = new Map<string, Promise<Buffer>>();
function getCachedOgImage(cacheKey: string, title: string, size: 'og' | 'twitter'): Promise<Buffer> {
let pngPromise = imagePromiseCache.get(cacheKey);
if (!pngPromise) {
pngPromise = renderOgImage({ title, size }).catch((error) => {
imagePromiseCache.delete(cacheKey);
throw error;
});
imagePromiseCache.set(cacheKey, pngPromise);
}
return pngPromise;
}
export const GET: APIRoute = async ({ params }) => {
// Dynamic mode intentionally uses a whitelist of known site paths instead of
// allowing arbitrary title or slug inputs.
const ogRequest = await resolveOgRequest(params.path);
if (!ogRequest) {
return new Response('Not found', {
status: 404,
headers: { 'Cache-Control': 'public, max-age=0, must-revalidate' },
});
}
const cacheKey = `${ogRequest.size}:${ogRequest.sitePath}`;
const png = await getCachedOgImage(cacheKey, ogRequest.title, ogRequest.size);
return new Response(new Uint8Array(png), {
headers: {
'Content-Type': 'image/png',
...getOgCacheHeaders(),
},
});
};