import fs from 'fs' import path from 'path' import { ImageResponse } from 'next/og' import { SITE_NAME, SITE_URL } from '@/app/metadata' export const ogImageSize = { width: 1200, height: 630 } const colors = { bg: '#040404', fg: '#e0e0e0', fgDim: '#b0b0b0', accent: '#ef1f1f' } function toDataUri(filePath: string, mime: string) { return `data:${mime};base64,${fs.readFileSync(filePath).toString('base64')}` } const logo = toDataUri(path.join(process.cwd(), 'public/logo.png'), 'image/png') type OgCardProps = { title: string description?: string eyebrow?: string } /** Renders the branded title card used for pages and posts without a cover image. */ export function renderOgCard({ title, description, eyebrow }: OgCardProps) { return new ImageResponse(
{eyebrow && (
{eyebrow}
)}
50 ? 60 : 76, fontWeight: 700, lineHeight: 1.1 }}> {title}
{description && (
{description.length > 140 ? description.slice(0, 137).trimEnd() + '…' : description}
)}
{/* oxlint-disable-next-line nextjs/no-img-element -- Satori renders plain only */} {SITE_NAME} {SITE_URL.replace(/^https?:\/\//, '')}
, ogImageSize, ) } const coverMimeTypes: Record = { '.png': 'image/png', '.jpg': 'image/jpeg', '.jpeg': 'image/jpeg', } /** Renders a post's cover image at OG size, or null if the format isn't supported by Satori. */ export function renderOgCover(coverImage: string) { const mime = coverMimeTypes[path.extname(coverImage).toLowerCase()] if (!mime) return null const src = toDataUri(path.join(process.cwd(), 'public/posts', coverImage), mime) return new ImageResponse( // oxlint-disable-next-line nextjs/no-img-element -- Satori renders plain only , ogImageSize, ) }