← back to Stayclaim
src/app/entity/[slug]/opengraph-image.tsx
92 lines
import { ImageResponse } from 'next/og';
import { headers } from 'next/headers';
import { getEntityBySlug } from '@/lib/db';
import { siteForHost } from '@/lib/site';
export const runtime = 'nodejs';
export const size = { width: 1200, height: 630 };
export const contentType = 'image/png';
export default async function og({ params }: { params: { slug: string } }) {
const h = await headers();
const surface = siteForHost(h.get('x-pastdoor-host') || h.get('host'));
const entity = await getEntityBySlug(params.slug);
const name = entity?.display_name ?? 'Entity';
const vitals = entity
? [entity.birth_year ?? '?', entity.death_year ?? '?'].join('–')
: '';
const kindLabel =
entity?.kind === 'architect'
? 'Architect'
: entity?.kind === 'studio'
? 'Studio'
: entity?.kind === 'business'
? 'Business'
: 'Person';
return new ImageResponse(
(
<div
style={{
width: '100%',
height: '100%',
display: 'flex',
flexDirection: 'column',
justifyContent: 'space-between',
padding: '64px',
background: '#1a1410',
color: '#f6f1e8',
fontFamily: 'Georgia, serif',
}}
>
<div style={{ display: 'flex', alignItems: 'baseline', gap: 12, fontSize: 24 }}>
<span style={{ fontFamily: 'Georgia, serif' }}>{surface.brandName}</span>
<span style={{ color: '#d4664a' }}>·</span>
<span style={{ fontSize: 16, letterSpacing: 2, textTransform: 'uppercase', color: 'rgba(246,241,232,0.55)' }}>
{kindLabel}
</span>
</div>
<div style={{ display: 'flex', flexDirection: 'column' }}>
<div
style={{
fontSize: 32,
letterSpacing: 4,
textTransform: 'uppercase',
color: 'rgba(246,241,232,0.55)',
marginBottom: 24,
}}
>
{vitals}
</div>
<div
style={{
fontSize: 112,
lineHeight: 1.02,
letterSpacing: '-0.02em',
color: '#f6f1e8',
maxWidth: '92%',
}}
>
{name}
</div>
</div>
<div
style={{
display: 'flex',
justifyContent: 'space-between',
alignItems: 'baseline',
fontSize: 18,
color: 'rgba(246,241,232,0.55)',
}}
>
<span>Historical associations only.</span>
<span style={{ fontFamily: 'Menlo, monospace', fontSize: 14, letterSpacing: 1 }}>
{surface.domain}
</span>
</div>
</div>
),
{ ...size }
);
}