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,
)
}