import {ImageResponse} from '@vercel/og' import {ogProps} from 'common/profiles/og-image' import {NextRequest} from 'next/server' import {classToTw} from 'web/components/og/utils' type ImageResponseOptions = ConstructorParameters[1] export const config = {runtime: 'edge'} const COMPASS_LOGO = 'https://firebasestorage.googleapis.com/v0/b/compass-130ba.firebasestorage.app/o/misc%2Fcompass-512.png?alt=media&token=d2fa566f-f443-4a94-90be-e50403f1805a' export const getCardOptions = async () => ({width: 1200, height: 630}) function capitalize(str: string) { if (!str) return '' return str.charAt(0).toUpperCase() + str.slice(1).toLowerCase() } // Palette const C = { ink900: '#1E1A14', ink600: '#786C5C', ink500: '#8C8070', ink300: '#BEB2A2', canvas50: '#F7F4EF', canvas100: '#EDE8E0', canvas200: '#E8D5BC', canvas300: '#DECBB2', canvas950: '#2C2416', primary50: '#FAF3E9', primary100: '#F3E4CE', primary200: '#E8C99D', primary300: '#DCAB71', primary400: '#D09352', primary500: '#C17F3E', primary600: '#A6682E', primary700: '#855022', primary800: '#653A18', } function OgProfile(props: ogProps) { const {avatarUrl, name, city, country, age, interests, keywords} = props let headline = props.headline const keywordsList = typeof keywords === 'string' ? (keywords ? keywords.split(',') : []) : (keywords ?? []) const interestsList = typeof interests === 'string' ? (interests ? interests.split(',') : []) : (interests ?? []) const allTags = [...keywordsList, ...interestsList].filter(Boolean).slice(0, 6) const maxChars = 250 if (headline && headline.length > maxChars) { headline = headline.slice(0, maxChars) + '…' } const hasLongContent = (headline?.length || 0) > 80 || allTags.length > 4 const imgSize = 300 return (
{/* Left dark panel */}
{/* Amber ring behind avatar */}
Avatar
{/* Compass URL */}
compassmeet.com
{/* Subtle bottom accent line */}
{/* Right content area */}
{/* Top accent line */}
{/* Name + age */}
{name} {age && ( {age} )}
{/* Location */} {(city || country) && (
{[city, country].filter(Boolean).join(', ')}
)} {/* Tags */} {allTags.length > 0 && (
{allTags.map(capitalize).map((tag, i) => ( {tag.trim()} ))}
)} {/* Headline */} {headline && (
{headline}
)}
) } export default async function handler(req: NextRequest) { try { const {searchParams} = new URL(req.url) const options = await getCardOptions() const cleanedEntries = Array.from(searchParams.entries()).map(([key, value]) => [ key.replace(/^amp;/, ''), value, ]) const ogProps = Object.fromEntries(cleanedEntries) as ogProps const image = OgProfile(ogProps) return new ImageResponse(classToTw(image), options as ImageResponseOptions) } catch (e: any) { console.error(`Failed to generate OG image for URL: ${req.url}`, e) return new Response('Failed to generate the image', {status: 500}) } }