From ff2b05a2e66af056de72a12d568aa2df39ae15c0 Mon Sep 17 00:00:00 2001 From: Duncan Crawbuck Date: Thu, 19 Feb 2026 12:13:29 -0800 Subject: [PATCH] Fix Cloudflare OG image 500 errors --- src/app/og/ai/route.tsx | 5 ++-- src/app/og/docs/[...slug]/route.tsx | 5 ++-- src/app/og/sdk/route.tsx | 5 ++-- src/lib/og.tsx | 43 ++++------------------------- 4 files changed, 14 insertions(+), 44 deletions(-) diff --git a/src/app/og/ai/route.tsx b/src/app/og/ai/route.tsx index f4681893..0cdaa81c 100644 --- a/src/app/og/ai/route.tsx +++ b/src/app/og/ai/route.tsx @@ -6,6 +6,7 @@ const description = 'Get instant answers to your questions about Superwall.'; export const revalidate = false; -export async function GET() { - return renderOgImage({ title, description, site: SITE_NAME }); +export async function GET(req: Request) { + const logoUrl = new URL('/docs/resources/logo.svg', req.url).toString(); + return renderOgImage({ title, description, site: SITE_NAME, logoUrl }); } diff --git a/src/app/og/docs/[...slug]/route.tsx b/src/app/og/docs/[...slug]/route.tsx index 3c970a9d..fc659be5 100644 --- a/src/app/og/docs/[...slug]/route.tsx +++ b/src/app/og/docs/[...slug]/route.tsx @@ -6,7 +6,7 @@ import { DEFAULT_DESCRIPTION, SITE_NAME } from '@/lib/metadata'; export const revalidate = false; export async function GET( - _req: Request, + req: Request, context: { params: Promise<{ slug: string[] }> }, ) { const params = await context.params; @@ -17,6 +17,7 @@ export async function GET( const title = page.data.title || SITE_NAME; const description = page.data.description || DEFAULT_DESCRIPTION; + const logoUrl = new URL('/docs/resources/logo.svg', req.url).toString(); - return renderOgImage({ title, description, site: SITE_NAME }); + return renderOgImage({ title, description, site: SITE_NAME, logoUrl }); } diff --git a/src/app/og/sdk/route.tsx b/src/app/og/sdk/route.tsx index 0f99d148..0bd58b79 100644 --- a/src/app/og/sdk/route.tsx +++ b/src/app/og/sdk/route.tsx @@ -6,6 +6,7 @@ const description = 'Select your SDK to view the specific documentation for this export const revalidate = false; -export async function GET() { - return renderOgImage({ title, description, site: SITE_NAME }); +export async function GET(req: Request) { + const logoUrl = new URL('/docs/resources/logo.svg', req.url).toString(); + return renderOgImage({ title, description, site: SITE_NAME, logoUrl }); } diff --git a/src/lib/og.tsx b/src/lib/og.tsx index b84cfbd8..3c1c4df7 100644 --- a/src/lib/og.tsx +++ b/src/lib/og.tsx @@ -1,31 +1,6 @@ -import { readFile } from 'fs/promises'; import { ImageResponse } from 'next/og'; -import { Buffer } from 'buffer'; -import { fileURLToPath } from 'url'; import { DEFAULT_DESCRIPTION, SITE_NAME } from '@/lib/metadata'; -const assetPath = (path: string) => fileURLToPath(new URL(path, import.meta.url)); - -const toArrayBuffer = (buffer: Buffer) => { - const arrayBuffer = new ArrayBuffer(buffer.byteLength); - new Uint8Array(arrayBuffer).set(buffer); - return arrayBuffer; -}; - -const interRegular = readFile( - assetPath('../assets/fonts/Inter-Regular.ttf'), -).then((buffer) => toArrayBuffer(buffer)); -const interSemiBold = readFile( - assetPath('../assets/fonts/Inter-SemiBold.ttf'), -).then((buffer) => toArrayBuffer(buffer)); -const interBold = readFile( - assetPath('../assets/fonts/Inter-Bold.ttf'), -).then((buffer) => toArrayBuffer(buffer)); -const logoSvg = readFile( - assetPath('../assets/logo.svg'), - 'utf-8', -).then((svg) => `data:image/svg+xml;base64,${Buffer.from(svg).toString('base64')}`); - function truncateText(value: string, maxLength: number) { if (value.length <= maxLength) return value; const ellipsis = '...'; @@ -37,26 +12,23 @@ type OgImageOptions = { title: string; description?: string; site?: string; + logoUrl?: string; }; export async function renderOgImage({ title, description, site = SITE_NAME, + logoUrl, }: OgImageOptions) { - const [regular, semiBold, bold, logo] = await Promise.all([ - interRegular, - interSemiBold, - interBold, - logoSvg, - ]); - const displayDescription = truncateText( description?.trim() || DEFAULT_DESCRIPTION, 180, ); const displayTitle = truncateText(title.trim(), 110); const titleSize = displayTitle.length > 70 ? 52 : 64; + const logo = logoUrl || 'https://superwall.com/docs/resources/logo.svg'; + return new ImageResponse( (
@@ -125,11 +97,6 @@ export async function renderOgImage({ { width: 1200, height: 630, - fonts: [ - { name: 'Inter', data: regular, weight: 400, style: 'normal' }, - { name: 'Inter', data: semiBold, weight: 600, style: 'normal' }, - { name: 'Inter', data: bold, weight: 700, style: 'normal' }, - ], }, ); }