Dynamic OG Image Service
Build on-the-fly social preview images using Supacrawler screenshots. Generate beautiful Open Graph images dynamically using Supacrawler's screenshot API.
APIs Used
This use case relies on the Screenshots API to capture dynamic content and generate images.
Quick Example
from supacrawler import SupacrawlerClient
import os
client = SupacrawlerClient(api_key=os.environ['SUPACRAWLER_API_KEY'])
def generate_og_image(url):
# Create screenshot with OG dimensions
job = client.create_screenshot_job(
url=url,
device="custom",
width=1200,
height=630, # Standard OG image size
format="png",
wait_until="networkidle"
)
# Wait for completion
result = client.wait_for_job(job.job_id)
return result.data.screenshot
og_image_url = generate_og_image("https://your-blog.com/article")
print(f"OG Image: {og_image_url}")
Next.js API Route
// pages/api/og-image.ts
import { NextApiRequest, NextApiResponse } from 'next'
import { SupacrawlerClient } from '@supacrawler/js'
const client = new SupacrawlerClient({
apiKey: process.env.SUPACRAWLER_API_KEY
})
export default async function handler(
req: NextApiRequest,
res: NextApiResponse
) {
const { url } = req.query
if (!url || typeof url !== 'string') {
return res.status(400).json({ error: 'URL required' })
}
try {
const job = await client.createScreenshotJob({
url,
device: 'custom',
width: 1200,
height: 630,
format: 'png'
})
const result = await client.waitForJob(job.job_id)
// Redirect to screenshot
res.redirect(result.data.screenshot)
} catch (error) {
res.status(500).json({ error: 'Failed to generate OG image' })
}
}
Custom Template
def generate_custom_og_image(title, description, author):
html_template = f"""
<!DOCTYPE html>
<html>
<head>
<style>
body {{
width: 1200px;
height: 630px;
display: flex;
flex-direction: column;
justify-content: center;
padding: 80px;
background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
color: white;
font-family: Arial, sans-serif;
}}
h1 {{ font-size: 72px; margin-bottom: 20px; }}
p {{ font-size: 32px; opacity: 0.9; }}
</style>
</head>
<body>
<h1>{title}</h1>
<p>{description}</p>
<p style="margin-top: 40px; font-size: 24px;">By {author}</p>
</body>
</html>
"""
# Save and screenshot
with open('/tmp/og-template.html', 'w') as f:
f.write(html_template)
job = client.create_screenshot_job(
url=f"file:///tmp/og-template.html",
width=1200,
height=630
)
return client.wait_for_job(job.job_id).data.screenshot
Best Practices
- Cache generated images for performance
- Use custom dimensions (1200x630) for social platforms
- Wait for
networkidle
for dynamic content - Hide cookie banners and ads
- Store in CDN for fast delivery
- Add fallback images for errors
Was this page helpful?