Products that list links live or die on visual previews: a wall of favicons converts worse than a grid of real page snapshots. The challenge is generating thousands of previews consistently — same viewport, no cookie banners photobombing half the grid, sensible behavior when a site is slow.
Screenshotty handles the rendering details; you store the result (or hotlink the JSON-mode hosted URL) and refresh on whatever schedule your content needs.
async function thumbnailFor(siteUrl) {const res = await fetch("https://api.screenshotty.link/api/v1/screenshot", {method: "POST",headers: {"X-Api-Key": process.env.SCREENSHOTTY_API_KEY,"Content-Type": "application/json",},body: JSON.stringify({url: siteUrl,viewport_width: 1280,viewport_height: 800,format: "image/webp",block_cookie_banner: true,adblock: true,response_type: "json",}),});const { url } = await res.json();return url; // store on the listing record}
Fixed viewport + ad/banner blocking gives every card in your directory the same clean look.
Capture at full size and resize downstream, or set a small viewport with device_scale_factor for crisp thumbs.
Re-capture on a schedule or when users update their listing — one request per refresh.
Clear error responses let you fall back to a placeholder instead of a broken image.
WebP is usually the sweet spot for preview grids — much smaller than PNG with quality fine for thumbnails. Use JPEG if you need maximum client compatibility.
Re-capture on a rolling schedule (e.g. each listing every N days) plus event-driven refreshes. With pay-as-you-go overage you can burst a full refresh without hitting a wall.
Yes. 100 screenshots per month free, no credit card required. Paid plans start at $9/month for 2,500 screenshots with $0.004 pay-as-you-go overage.
Use response_type=json at generation time and store the returned hosted image URL — that keeps your API key server-side and your pages fast.