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
A good link preview includes:
- 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
The flow works like this:
- User pastes a URL in your app
- Your backend fetches the page metadata (title, description, favicon)
- Your backend requests a screenshot thumbnail from PxShot
- You cache both the metadata and screenshot
- The frontend renders a rich preview card
Backend: Fetch Metadata + Screenshot
async function generatePreview(url: string) {
// Fetch page metadata
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] || '';
// Capture thumbnail via PxShot
const screenshot = await fetch(
`https://pxshot.dev/api/capture?url=${encodeURIComponent(url)}&width=800&height=450&format=webp&quality=75&key=${API_KEY}`
);
const imageBlob = await screenshot.arrayBuffer();
// Store in your object storage (R2, S3, etc.)
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
Link previews should be cached aggressively since pages rarely change:
- 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.