All checks were successful
Generate a build and push to Cloudflare Pages / Build and Deploy to Cloudflare Pages (push) Successful in 1m24s
155 lines
5.1 KiB
TypeScript
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)
|
|
})
|