Why Social Media Cards Matter
When someone shares your link on Twitter, LinkedIn, or Facebook, the platform fetches your Open Graph (OG) metadata and renders a preview card. A well-designed card can increase click-through rates by 2-3x compared to a plain text link.
The problem? Manually creating unique OG images for every page is tedious. If you have hundreds of blog posts, product pages, or landing pages, you need automation.
This guide shows you how to use the ToolCenter to generate beautiful social media cards programmatically.
How Social Media Cards Work
Social platforms read specific meta tags from your HTML:
<meta property="og:title" content="Your Page Title" />
<meta property="og:description" content="A brief description" />
<meta property="og:image" content="https://example.com/og-image.png" />
<meta property="og:url" content="https://example.com/page" />
<meta name="twitter:card" content="summary_large_image" />
The og:image tag is the most impactful. Without it, platforms show a generic placeholder or nothing at all.
Generating OG Images with ToolCenter
The ToolCenter Screenshot API can render custom HTML templates into perfectly-sized OG images. Here’s the approach:
Step 1: Create an HTML Template
Design a template for your social cards:
<div style="width:1200px;height:630px;display:flex;flex-direction:column;
justify-content:center;padding:60px;background:linear-gradient(135deg,#667eea,#764ba2);
font-family:system-ui;color:white;">
<h1 style="font-size:56px;margin:0 0 20px;line-height:1.2;">{{title}}</h1>
<p style="font-size:24px;opacity:0.9;margin:0 0 40px;">{{description}}</p>
<div style="display:flex;align-items:center;gap:12px;">
<img src="{{logo}}" style="width:40px;height:40px;border-radius:50%;" />
<span style="font-size:20px;">yourbrand.com</span>
</div>
</div>
Step 2: Render with the Screenshot API
Use the ToolCenter to convert your HTML template into an image:
const axios = require('axios');
async function generateOGImage(title, description) {
const html = `
<div style="width:1200px;height:630px;display:flex;flex-direction:column;
justify-content:center;padding:60px;background:linear-gradient(135deg,#667eea,#764ba2);
font-family:system-ui;color:white;">
<h1 style="font-size:56px;margin:0 0 20px;line-height:1.2;">${title}</h1>
<p style="font-size:24px;opacity:0.9;">${description}</p>
</div>
`;
const response = await axios.post(
'https://api.toolcenter.dev/v1/screenshot',
{
html: html,
width: 1200,
height: 630,
format: 'png'
},
{
headers: { 'Authorization': 'Bearer YOUR_API_KEY' },
responseType: 'arraybuffer'
}
);
return response.data;
}
Step 3: Automate for All Pages
Build a script that processes all your pages:
const fs = require('fs');
const path = require('path');
const pages = [
{ slug: 'getting-started', title: 'Getting Started Guide', desc: 'Everything you need to begin' },
{ slug: 'pricing', title: 'Simple Pricing', desc: 'Plans that scale with you' },
// ... more pages
];
async function generateAllCards() {
for (const page of pages) {
const imageBuffer = await generateOGImage(page.title, page.desc);
const outputPath = path.join('./public/og', `${page.slug}.png`);
fs.writeFileSync(outputPath, imageBuffer);
console.log(`Generated: ${outputPath}`);
}
}
generateAllCards();
Python Implementation
import requests
def generate_og_image(title, description, output_path):
html = f"""
<div style="width:1200px;height:630px;display:flex;flex-direction:column;
justify-content:center;padding:60px;background:linear-gradient(135deg,#667eea,#764ba2);
font-family:system-ui;color:white;">
<h1 style="font-size:56px;margin:0 0 20px;">{title}</h1>
<p style="font-size:24px;opacity:0.9;">{description}</p>
</div>
"""
response = requests.post(
'https://api.toolcenter.dev/v1/screenshot',
json={
'html': html,
'width': 1200,
'height': 630,
'format': 'png'
},
headers={'Authorization': 'Bearer YOUR_API_KEY'}
)
with open(output_path, 'wb') as f:
f.write(response.content)
# Generate cards for all blog posts
posts = [
("My First Post", "An introduction to our blog"),
("Product Update", "What's new in version 2.0"),
]
for title, desc in posts:
slug = title.lower().replace(' ', '-')
generate_og_image(title, desc, f"./og-images/{slug}.png")
Integrating with Your Build Pipeline
Next.js Integration
Add OG image generation to your build process:
// next.config.js — use a custom build script
// scripts/generate-og.js
const { getAllPosts } = require('./lib/posts');
async function buildOGImages() {
const posts = getAllPosts();
for (const post of posts) {
await generateOGImage(post.title, post.excerpt);
}
}
buildOGImages();
CI/CD Pipeline
Add to your GitHub Actions workflow:
- name: Generate OG Images
run: node scripts/generate-og-images.js
env:
DEVTOOLBOX_API_KEY: ${{ secrets.DEVTOOLBOX_API_KEY }}
Platform-Specific Sizes
Different platforms prefer different dimensions:
- Twitter (summary_large_image): 1200×628px
- LinkedIn: 1200×627px
- Facebook: 1200×630px
- Discord: 1200×630px
The sweet spot is 1200×630px — it works well across all platforms.
Caching and Performance
Don’t regenerate images on every request. Instead:
- Generate at build time — Create images during your CI/CD pipeline
- Cache aggressively — Store generated images in a CDN
- Use content hashing — Only regenerate when the title or description changes
const crypto = require('crypto');
function getImageHash(title, description) {
return crypto.createHash('md5')
.update(`${title}-${description}`)
.digest('hex')
.slice(0, 8);
}
Testing Your Cards
Before deploying, validate your OG tags:
- Twitter Card Validator: cards-dev.twitter.com/validator
- Facebook Sharing Debugger: developers.facebook.com/tools/debug
- LinkedIn Post Inspector: linkedin.com/post-inspector
Conclusion
Automating social media card generation saves hours of design work and ensures every page on your site has a compelling preview. The ToolCenter Screenshot API makes it straightforward to render custom HTML templates into perfectly-sized OG images, integrate with your build pipeline, and serve them at scale.