Building a Thumbnail Service
Website thumbnails are small preview images of web pages, used in link aggregators, search results, and content directories. This tutorial builds a complete thumbnail generation service with Node.js.
Basic Thumbnail Generation
import express from 'express';
import crypto from 'crypto';
import fs from 'fs';
import path from 'path';
const app = express();
const CACHE_DIR = './thumbnails';
const API_KEY = process.env.SNAPAPI_KEY;
if (!fs.existsSync(CACHE_DIR)) fs.mkdirSync(CACHE_DIR, { recursive: true });
app.get('/thumb', async (req, res) => {
const { url } = req.query;
if (!url) return res.status(400).json({ error: 'URL required' });
// Generate cache key from URL
const hash = crypto.createHash('md5').update(url).digest('hex');
const cachePath = path.join(CACHE_DIR, hash + '.jpg');
// Serve cached version if exists
if (fs.existsSync(cachePath)) {
return res.sendFile(path.resolve(cachePath));
}
// Generate new thumbnail
const ssRes = await fetch(
`https://apisnap.dev/api/screenshot?url=${encodeURIComponent(url)}&format=jpeg&quality=75&width=640&height=400`,
{ headers: { Authorization: `Bearer ${API_KEY}` } }
);
if (!ssRes.ok) return res.status(502).json({ error: 'Capture failed' });
const buffer = Buffer.from(await ssRes.arrayBuffer());
fs.writeFileSync(cachePath, buffer);
res.set('Content-Type', 'image/jpeg');
res.send(buffer);
});
app.listen(3000);Cache Management
Thumbnails should be cached for days or weeks since most pages don't change frequently. Implement a TTL-based cache that automatically refreshes stale thumbnails. Use file modification timestamps to determine cache freshness.
Error Handling
Always have a fallback thumbnail for failed captures. This prevents broken images in your UI. Return a generic placeholder when the screenshot API returns an error or times out.