import fs from 'node:fs' import path from 'node:path' import { ImageResponse } from '@vercel/og' import { urlWithParams } from '../lib/urls' import type { Prettify } from 'ts-essentials' export type GenericOgImageProps = Partial> ////////////////////////////////////////////////////// // NOTE // // Use this website to create and preview templates // // https://og-playground.vercel.app/ // ////////////////////////////////////////////////////// const defaultOptions = { width: 1200, height: 630, fonts: [ { name: 'Inter', weight: 400, style: 'normal', data: fs.readFileSync( path.resolve( process.cwd(), 'node_modules', '@fontsource', 'inter', 'files', 'inter-latin-400-normal.woff' ) ), }, { name: 'Inter', weight: 700, style: 'normal', data: fs.readFileSync( path.resolve( process.cwd(), 'node_modules', '@fontsource', 'inter', 'files', 'inter-latin-700-normal.woff' ) ), }, ], } as const satisfies ConstructorParameters[1] export const ogImageTemplates = { default: () => { return new ImageResponse( (
), defaultOptions ) }, generic: ({ title }: { title?: string }) => { return new ImageResponse( (
{title}
), defaultOptions ) }, } as const satisfies Record ImageResponse | null> type OgImageTemplate = keyof typeof ogImageTemplates type OgImageProps = Parameters<(typeof ogImageTemplates)[T]>[0] // eslint-disable-next-line @typescript-eslint/sort-type-constituents export type OgImageAllTemplatesWithGenericProps = { template: OgImageTemplate } & GenericOgImageProps export type OgImageAllTemplatesWithProps = Prettify< { // eslint-disable-next-line @typescript-eslint/sort-type-constituents [K in OgImageTemplate]: { template: K } & Omit, 'template'> }[OgImageTemplate] > export function makeOgImageUrl( ogImage: OgImageAllTemplatesWithProps | string | undefined, baseUrl: URL | string ) { return typeof ogImage === 'string' ? new URL(ogImage, baseUrl).href : urlWithParams(new URL('/ogimage.png', baseUrl), ogImage ?? {}) }