Home/Blog/Build Rich Link Previews with Screenshot APIs

Build Rich Link Previews with Screenshot APIs

December 2, 2025tutorials1 min read

Building Rich Link Previews

Link previews transform plain URLs into engaging visual cards that drive clicks. Screenshot-based previews are more accurate and compelling than OG-tag-only previews because they show the actual page content.

Architecture

A link preview service follows this pattern:

  1. User submits a URL
  2. Backend captures a screenshot at preview dimensions (1200x630)
  3. Screenshot is cached with a unique key derived from the URL
  4. Cached image is served for all subsequent requests
  5. Cache refreshes periodically based on a TTL

Implementation

import express from 'express';
import crypto from 'crypto';

const app = express();
const cache = new Map();

app.get('/preview', async (req, res) => {
  const url = req.query.url;
  if (!url) return res.status(400).json({ error: 'URL required' });

  const key = crypto.createHash('sha256').update(url).digest('hex');

  if (cache.has(key)) {
    const { image, timestamp } = cache.get(key);
    if (Date.now() - timestamp < 86400000) { // 24h cache
      res.set('Content-Type', 'image/jpeg');
      return res.send(image);
    }
  }

  const ssRes = await fetch(
    `https://apisnap.dev/api/screenshot?url=${encodeURIComponent(url)}&format=jpeg&quality=80&width=1200&height=630`,
    { headers: { Authorization: `Bearer ${process.env.SNAPAPI_KEY}` } }
  );

  if (!ssRes.ok) return res.status(502).json({ error: 'Preview failed' });

  const image = Buffer.from(await ssRes.arrayBuffer());
  cache.set(key, { image, timestamp: Date.now() });
  res.set('Content-Type', 'image/jpeg');
  res.send(image);
});

Optimization Tips

Use Redis or Memcached for shared caching across instances. Set appropriate TTLs: 24 hours for news sites, 7 days for static pages. Always have a fallback image for failed captures. Use JPEG format for link previews to keep file sizes small.