Back to blog

Capture guides

How to Generate a Website Thumbnail from a URL (Automatically)

June 23, 2026 · 6 min read · Grabbit Team

How to Generate a Website Thumbnail from a URL (Automatically)

A website thumbnail is a small preview image of a web page, almost always a scaled-down screenshot of the page rendered in a real browser. Directories, link galleries, portfolio grids, bookmark managers, and admin dashboards all use them so a visitor can recognize a site at a glance. To generate one automatically from a URL, send the URL to a screenshot API and store the image it returns.

The hard part is never the thumbnail itself. It is rendering the page faithfully, at the right size, for many URLs, on a schedule, without running a browser fleet yourself. This guide covers what a thumbnail actually is, what size to capture, the build-it-yourself path, and the one-call API path.

These get confused because both are "a small image of a page," but they are different jobs:

  • A website thumbnail is a screenshot of the page. You generate it for sites you list, link to, or manage. It updates when you recapture.
  • A social link preview is the og:image a site sets for itself, shown when its link is shared on Slack, Discord, or X. It is a hand-designed card, not a live screenshot, and you control it only for your own pages.

This post is about the first one: turning a URL into a real rendered screenshot you can display. If you are trying to fix the card that shows when your own link is shared, that is an Open Graph problem, not a thumbnail problem.

What size should a website thumbnail be

Capture at a desktop viewport width, then display the result scaled down. The two decisions are separate:

  • Capture width sets which layout renders. 1280px is a safe default: it triggers the desktop layout the way most visitors see the site. Rendering at a tiny viewport instead pushes the page into its mobile breakpoint, so your thumbnail shows a hamburger menu and a single stacked column, which is not what a "website thumbnail" is meant to convey.
  • Displayed size is a CSS concern. Common thumbnail dimensions are 320x240, 480x360, and 600x400, all 4:3. You downscale the captured image into that box in your grid.

So the rule is: capture wide and faithful, display small. A full-width capture downscaled in CSS keeps text crisp and the layout recognizable. A page rendered at thumbnail dimensions does not.

For just the top of the page (the most common thumbnail framing), capture a fixed height rather than the full page. A 1280x720 capture gives you a clean 16:9 hero crop of what is above the fold.

The build-it-yourself path

You can generate thumbnails with headless Chrome. The shape in Puppeteer:

// DIY: you own the browser, the scaling, and the storage
const browser = await puppeteer.launch();
const page = await browser.newPage();
await page.setViewport({ width: 1280, height: 720 });
await page.goto(url, { waitUntil: 'networkidle2' });
const buffer = await page.screenshot({ type: 'png' });
await browser.close();
// then: resize, upload to storage, store the URL

That works for one URL on your laptop. The cost shows up at scale:

  • Infrastructure. Each capture needs a Chromium process. Generating thumbnails for a directory of hundreds of sites means a browser pool, queueing, and memory limits, because one runaway page can take down the box.
  • Reliability. Cookie and consent banners, lazy-loaded images, and pages that block headless browsers all produce blank or broken thumbnails unless you handle each case.
  • Storage. You still have to resize, upload, and serve every image yourself.

For a handful of static thumbnails this is fine. For an automated, always-current gallery it becomes a service you maintain.

The one-call API path

A screenshot API does the rendering and hosting so your code is just the request. Send the URL, get back a hosted image:

curl https://api.grabbit.live/v1/grabs \
  -H "Authorization: Bearer sk_live_..." \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://stripe.com",
    "width": 1280,
    "height": 720,
    "format": "webp"
  }'

width pins the desktop layout. height of 720 gives a 16:9 above-the-fold crop, the classic thumbnail frame. format of webp keeps the file small, which matters when a grid loads dozens of thumbnails at once. The response includes an image_url pointing at the stored capture. Save that URL and render it in your <img> or as a CSS background-image in the grid cell.

Want the entire page instead of the top crop? Set "full_page": true and drop height. For pages with content that loads after the initial paint, add "delay_ms": 800 so lazy images settle before the capture. To thumbnail a specific element, such as a hero section or a card, pass "selector": "#hero" and only that element is captured.

Generating thumbnails in bulk

A directory or gallery is the same request in a loop. There is no separate batch endpoint to learn:

  1. Iterate over your list of URLs.
  2. Call the API once per URL with the same width, height, and format.
  3. Store each returned image_url keyed by the source URL.
  4. Render the stored URLs in your grid.

Because the API owns the browser pool, capturing a hundred thumbnails is the same code as capturing one. If you are building this around a list of sites, how to screenshot a list of URLs covers the loop, concurrency, and error handling in depth.

Keeping thumbnails current

A thumbnail goes stale the moment the source site redesigns. The fix is to recapture, but recapturing every page on every render is wasteful. The pattern:

  • Cache the image_url. Store it with the source URL and a captured-at timestamp. Serve the cached image, not a fresh capture, on every page load.
  • Refresh on a schedule. Recapture each URL on a cadence that matches how often the sites actually change. A daily refresh is plenty for most directories; a weekly one is fine for stable portfolio sites.
  • Refresh on demand. Let users trigger a recapture for their own listing so a redesign shows up immediately instead of waiting for the next scheduled run.

This keeps the gallery current without rendering a browser on every request.

Putting it together

To generate a website thumbnail from a URL automatically: capture at a desktop width, request a small format, store the returned image URL, and recapture on a schedule. With a hosted API the whole thing is one request per URL plus a cache, no browser fleet to run.

For the full set of capture options (viewport, format, full-page, selector, delay) see the screenshot API. For running captures across many URLs on a schedule, see automated screenshots. And if you only need the top crop versus the whole document, how to screenshot a website from a URL walks through the framing choices in detail.

FAQ

What is a website thumbnail?
A website thumbnail is a small image that previews what a web page looks like, usually a scaled-down screenshot of the page rendered in a browser. Directories, dashboards, link galleries, and portfolio grids use them so a visitor can recognize a site at a glance without loading it. It is distinct from a social link preview image (the og:image), which is a hand-set card shown when a link is shared.
How do I make a thumbnail for my website?
To generate a thumbnail of a page automatically, send the URL to a screenshot API and request a small capture. The API renders the page in a real browser and returns a hosted image you store and display. You can also do it yourself with headless Chrome (Puppeteer or Playwright), but you then own the browser infrastructure, scaling, and storage. For a single static thumbnail you can also screenshot the page manually and resize it, but that does not stay current as the site changes.
What size should a website thumbnail be?
Capture at a desktop viewport width (1280px is a common choice) so the layout renders the way visitors see it, then display the image scaled down in your grid. Common displayed thumbnail sizes are 320x240, 480x360, and 600x400, all 4:3. Capturing at full width and downscaling in CSS keeps text legible and the layout faithful, which is better than rendering at a tiny viewport where responsive breakpoints distort the page.
How do I change the thumbnail of a website?
If you mean the thumbnail your own site shows when shared on social media, that is controlled by the og:image meta tag, not a screenshot. If you mean a thumbnail you display for other sites in a gallery or directory, recapture the URL to get a fresh image and replace the stored one. Automating the recapture on a schedule keeps thumbnails current as the sites change.
Can I generate website thumbnails in bulk?
Yes. Loop over your list of URLs and call the screenshot API once per URL, storing each returned image. A hosted API handles the concurrency and browser pool for you, so capturing hundreds of thumbnails is the same code as capturing one, just in a loop. Cache the returned image URL so you only recapture when a site actually changes.

Capture any website with one API call

Get a free test key and capture your first screenshot in two minutes.

Written by

Grabbit Team

Screenshots as a service

The team behind Grabbit, the screenshot API for developers and AI agents. We write about web capture, rendering, and automating screenshots at scale.

Keep reading