Files
portfolio/scripts/generate-og-image.ts
patrick d21806dfd1
All checks were successful
Generate a build and push to Cloudflare Pages / Build and Deploy to Cloudflare Pages (push) Successful in 1m24s
initial commit
2026-03-25 18:53:21 -04:00

155 lines
5.1 KiB
TypeScript

import { ImageResponse } from '@vercel/og'
import { readFile, writeFile } from 'node:fs/promises'
import { join } from 'node:path'
async function generateOGImage() {
console.log('🎨 Generating OG image...')
const clashFont = await readFile(
join(process.cwd(), 'public/fonts/ClashDisplay/ClashDisplay-Semibold.woff')
)
const lexendFont = await readFile(
join(process.cwd(), 'public/fonts/Lexend/Lexend-Regular.woff')
)
const logoImage = await readFile(
join(process.cwd(), 'public/logo.svg')
)
const logoDataUri = `data:image/svg+xml;base64,${logoImage.toString('base64')}`
const imageResponse = new ImageResponse(
{
type: 'div',
props: {
style: {
height: '100%',
width: '100%',
display: 'flex',
alignItems: 'center',
justifyContent: 'center',
backgroundColor: '#2d2d2d',
backgroundImage: 'linear-gradient(135deg, rgba(235, 219, 147, 0.40) 0%, transparent 50%)',
padding: '80px',
},
children: [
{
type: 'div',
props: {
style: {
display: 'flex',
flexDirection: 'row',
alignItems: 'flex-start',
gap: '48px',
maxWidth: '1100px',
},
children: [
{
type: 'img',
props: {
src: logoDataUri,
alt: 'Patrick Jaroszewski Logo',
style: {
width: 183,
height: 247,
flexShrink: 0,
},
},
},
{
type: 'div',
props: {
style: {
display: 'flex',
flexDirection: 'column',
gap: '20px',
maxWidth: '820px',
},
children: [
{
type: 'div',
props: {
style: {
display: 'flex',
flexDirection: 'column',
gap: '8px',
},
children: [
{
type: 'div',
props: {
style: {
fontFamily: 'Lexend',
fontSize: 28,
fontWeight: 400,
color: '#c4c4c4',
},
children: 'Hello, I\'m',
},
},
{
type: 'div',
props: {
style: {
fontFamily: 'ClashDisplay',
fontSize: 60,
fontWeight: 600,
color: '#f2f2f2',
letterSpacing: '-1.5px',
lineHeight: 1.1,
},
children: 'Patrick Jaroszewski',
},
},
],
},
},
{
type: 'div',
props: {
style: {
fontFamily: 'Lexend',
fontSize: 22,
fontWeight: 400,
color: '#c4c4c4',
lineHeight: 1.6,
},
children: 'Full Stack Developer & DevOps Engineer passionate about building scalable web applications and robust infrastructure. A relentless learner driven by curiosity — skilled in modern web technologies, self-hosted infrastructure, and automation.',
},
},
],
},
},
],
},
},
],
},
},
{
width: 1200,
height: 630,
fonts: [
{ name: 'ClashDisplay', data: clashFont, weight: 600 },
{ name: 'Lexend', data: lexendFont, weight: 400 },
],
}
)
// Get the image as an ArrayBuffer
const arrayBuffer = await imageResponse.arrayBuffer()
const buffer = Buffer.from(arrayBuffer)
// Write to public directory
const outputPath = join(process.cwd(), 'public/ogImage.png')
await writeFile(outputPath, buffer)
console.log('✅ OG image generated successfully at public/ogImage.png')
console.log(` Size: ${(buffer.length / 1024).toFixed(2)} KB`)
}
// Run the generator
generateOGImage().catch((error) => {
console.error('❌ Failed to generate OG image:', error)
process.exit(1)
})