· Tutorials

How to Generate Social Cards with Screenshots

Learn how to create dynamic Open Graph images for your website using the RenderScreenshot API.

Social media icons on a phone

Social cards make your links stand out when shared on Twitter, LinkedIn, Slack, and other platforms. Instead of static images, you can generate them dynamically from your actual content.

In this tutorial, we'll show you how to use RenderScreenshot to create social cards automatically.

The Problem with Static Social Cards

Most websites use the same Open Graph image for every page, or worse, no image at all. This means:

  • Every link looks the same when shared
  • Content updates don't reflect in the preview
  • You need to manually create images for each page

Dynamic Social Cards

With RenderScreenshot, you can generate unique social cards for every page on your site. Here's how it works:

  1. Create a template page that displays your content nicely at 1200x630
  2. Use our API to capture a screenshot of that page
  3. Serve the screenshot URL as your og:image

Step 1: Create a Template

Create a route in your app that renders content optimized for social sharing:

<!-- /social-card?title=Hello%20World -->
<!DOCTYPE html>
<html>
<head>
  <style>
    body {
      width: 1200px;
      height: 630px;
      display: flex;
      align-items: center;
      justify-content: center;
      background: linear-gradient(135deg, #10b981, #059669);
      font-family: system-ui, sans-serif;
    }
    .card {
      text-align: center;
      color: white;
    }
    h1 {
      font-size: 64px;
      margin: 0;
    }
  </style>
</head>
<body>
  <div class="card">
    <h1>{{ title }}</h1>
    <p>yoursite.com</p>
  </div>
</body>
</html>

Step 2: Generate the Screenshot

Use the RenderScreenshot API with the og_card preset:

const screenshotUrl = `https://api.renderscreenshot.com/v1/screenshot?` +
  `url=${encodeURIComponent('https://yoursite.com/social-card?title=Hello')}&` +
  `preset=og_card&` +
  `api_key=rs_pub_...`;

The og_card preset automatically: - Sets dimensions to 1200x630 - Optimizes for fast loading - Caches for 24 hours

Step 3: Add to Your Meta Tags

Reference the screenshot URL in your page's meta tags:

<meta property="og:image" content="https://api.renderscreenshot.com/v1/screenshot?url=..." />
<meta property="og:image:width" content="1200" />
<meta property="og:image:height" content="630" />
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" content="https://api.renderscreenshot.com/v1/screenshot?url=..." />

Using Signed URLs

For production, use signed URLs to prevent abuse:

import { generateSignedUrl } from 'renderscreenshot';

const client = new RenderScreenshot({
  publicKey: 'rs_pub_...',
  secretKey: 'rs_secret_...'
});

const signedUrl = client.generateSignedUrl({
  url: 'https://yoursite.com/social-card?title=Hello',
  preset: 'og_card',
  expiresIn: '7d'
});

Signed URLs are safe to expose publicly because they can only be used for the specific parameters you signed.

Caching Strategy

Screenshots are cached automatically. The default TTL is 24 hours, but you can customize it:

// Cache for 7 days
const url = client.generateSignedUrl({
  url: 'https://yoursite.com/social-card',
  preset: 'og_card',
  cache: { ttl: '7d' }
});

For content that changes frequently, use a shorter TTL or include a cache-busting parameter:

const url = `...&v=${post.updatedAt.getTime()}`;

Testing Your Cards

Before deploying, test your social cards:

  1. Twitter Card Validator: cards-dev.twitter.com/validator
  2. Facebook Debugger: developers.facebook.com/tools/debug
  3. LinkedIn Inspector: linkedin.com/post-inspector

Complete Example

Here's a complete Next.js implementation:

// pages/api/og.ts
import { generateSignedUrl } from 'renderscreenshot';

export default function handler(req, res) {
  const { title, description } = req.query;

  const templateUrl = new URL('https://yoursite.com/og-template');
  templateUrl.searchParams.set('title', title);
  templateUrl.searchParams.set('description', description);

  const screenshotUrl = generateSignedUrl({
    publicKey: process.env.RS_PUBLIC_KEY,
    secretKey: process.env.RS_SECRET_KEY,
    url: templateUrl.toString(),
    preset: 'og_card',
    expiresIn: '30d'
  });

  res.redirect(screenshotUrl);
}

Then in your pages:

<meta property="og:image" content="/api/og?title=My%20Post&description=..." />

Have questions? Check our documentation or reach out at [email protected].