Back to blog
TutorialLink PreviewIntegration

How to Build a Link Preview Feature Using a Screenshot API

Add rich link previews to your app with visual thumbnails of any URL. Complete tutorial with frontend and backend code for building unfurl-style link cards.

2025-04-158 min read

Link previews — the visual cards that show a thumbnail, title, and description when you paste a URL — are one of the most engaging features you can add to a communication or content platform. Here's how to build one using a screenshot API.

What Makes a Great Link Preview

  • Visual thumbnail — A screenshot of the actual page
  • Page title — Extracted from the <title> or OG tags
  • Description — The meta description or OG description
  • Domain name — Shows the source for trust

Architecture Overview

  1. User pastes a URL in your app
  2. Your backend fetches the page metadata (title, description, favicon)
  3. Your backend requests a screenshot thumbnail from PxShot
  4. You cache both the metadata and screenshot
  5. The frontend renders a rich preview card

Backend: Fetch Metadata + Screenshot

async function generatePreview(url: string) {
  const page = await fetch(url);
  const html = await page.text();
  const title = html.match(/<title>([^<]+)<\/title>/)?.[1] || url;
  const desc = html.match(/meta.*?description.*?content="([^"]+)"/)?.[1] || '';

  const screenshot = await fetch(
    `https://pxshot.dev/api/capture?url=${encodeURIComponent(url)}&width=800&height=450&format=webp&quality=75&api_key=${API_KEY}`
  );
  const imageBlob = await screenshot.arrayBuffer();
  const imageUrl = await uploadToStorage(imageBlob, `previews/${hash(url)}.webp`);

  return { title, description: desc, imageUrl, domain: new URL(url).hostname };
}

Frontend: Render the Preview Card

function LinkPreview({ preview }) {
  return (
    <div className="link-preview">
      <img src={preview.imageUrl} alt={preview.title} />
      <div className="preview-info">
        <h4>{preview.title}</h4>
        <p>{preview.description}</p>
        <span className="domain">{preview.domain}</span>
      </div>
    </div>
  );
}

Caching Strategy

  • Cache previews in your database with a 24-hour TTL
  • Use the URL hash as the cache key
  • Allow users to manually refresh a preview if needed
  • Store screenshots in object storage (not your database)

Production Tips

  • Small viewport for thumbnails — Use 800×450 for preview cards to keep file sizes small
  • Use WebP format — 40% smaller than PNG at equivalent quality
  • Background processing — Generate previews asynchronously, show a placeholder meanwhile
  • Handle failures gracefully — Some sites block headless browsers; fall back to OG image or a generic card

With PxShot's free tier, you can build and test link previews without any upfront cost. Get your API key.