How to screenshot every page in a sitemap

Four ways to capture every page a sitemap lists, from a free script to hosted services, what each is good for, and the things that quietly ruin a batch of screenshots.

Dave Weatherall7 min read

Step one: find the sitemap

A sitemap is the list of pages a site wants search engines to find, which makes it the quickest route to a complete set of screenshots. Clicking through the navigation misses pages. The sitemap usually doesn't.

  • Open /robots.txt on the site. A line starting Sitemap: gives the exact address.
  • Otherwise try /sitemap.xml, then /sitemap_index.xml. WordPress sites also have /wp-sitemap.xml.
  • If the file lists other sitemaps instead of pages, it's an index. Each entry is a sitemap of its own, usually one per type: pages, posts, products.

A sitemap only includes pages the site chose to list. Anything marked noindex won't be there, and neither will most pages behind a login.

Four ways to capture the pages

MethodGood forWatch out for
By hand in a browserUp to about ten pagesTwo captures per page if you need mobile, and naming every file yourself
A scriptDevelopers who want it freeEvery problem in the next section is yours to solve
A hosted serviceCapturing on a schedule, over monthsAn ongoing cost, and every page renders on someone else's servers
A desktop appA whole site at both sizes, on your own machineSiteHaul is Mac only, and $49 past ten free pages a month

By hand

Chrome can capture a whole page without an extension. Open DevTools, press Cmd+Shift+P, type “screenshot” and choose Capture full size screenshot. Firefox has it on the right-click menu under Take Screenshot, then Save full page.

That's fine for a handful of pages. The work grows with the count, though. Twenty pages at desktop and mobile is forty captures, each needing the window resized and a filename you'll recognize later. An extension like GoFullPage is quicker per page but has the same arithmetic, which the SiteHaul vs GoFullPage comparison goes into.

A script

If you write code, Playwright can do this for free. This reads a sitemap and saves a full-page screenshot of every page it lists:

shots.mjs
import { chromium } from "playwright";
import { mkdirSync } from "node:fs";

const sitemap = "https://example.com/sitemap.xml";
const xml = await (await fetch(sitemap)).text();
const urls = [...xml.matchAll(/<loc>(.*?)<\/loc>/g)].map((m) => m[1]);

mkdirSync("shots", { recursive: true });
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1440, height: 900 } });

for (const url of urls) {
  await page.goto(url, { waitUntil: "load" });
  const name = new URL(url).pathname.replace(/^\/|\/$/g, "").replaceAll("/", "-") || "home";
  await page.screenshot({ path: `shots/${name}.png`, fullPage: true });
}
await browser.close();
Terminal
npm install playwright
npx playwright install chromium
node shots.mjs

If the sitemap is an index, its <loc> entries are more sitemaps, so fetch each of those and collect their pages instead. On a simple site that's the whole job. On most real sites, expect to spend longer on the problems below than on the script.

A hosted service

Stillio and Apify both take a sitemap and capture every page on their own servers. Stillio is built for capturing on a schedule, so it suits keeping a record of how a site changes over months. Apify charges by usage and suits developers who want the images through an API. Either way you pay for as long as you use it, and the pages are rendered and stored elsewhere, which matters for client work under NDA and for sites that aren't public yet.

A desktop app

This is what SiteHaul does. It reads the sitemap, shows you the pages grouped by type so you can untick what you don't need, and captures every one at desktop and mobile sizes in one run. It runs on your Mac, so nothing is uploaded, and it's free for ten pages a month, then $49 once.

  1. Paste the site's address and press Fetch pages. SiteHaul checks robots.txt and the usual sitemap locations, and follows sitemap indexes.
  2. Review the list. Pages arrive grouped as pages, blog posts, products and so on, and a whole group unticks at once.
  3. Leave Desktop and Mobile ticked and press Screenshot selected.
  4. Open the folder. Every file is named from its URL.
What you get
example.com-2026-09-25/
  desktop/
    home-desktop.png
    pricing-desktop.png
    blog-first-post-desktop.png
  mobile/
    home-mobile.png
    pricing-mobile.png
    blog-first-post-mobile.png
  urls.md

urls.md is every URL the sitemap listed, grouped by type. It's a useful record on its own, and the starting point for a redirect map if the site is about to be rebuilt.

SiteHaul's gallery after one run: every page of a site as desktop and mobile captures, side by side
One run of a 28 page site, desktop and mobile, named from each URL.

What quietly ruins a batch of screenshots

A tool that captures one page well can still fail across a whole site. These are the problems that turn up, all of them found capturing real sites. SiteHaul handles each one, and a script has to as well.

  • Cookie banners and popups. A consent banner sits across the top of every page, and a newsletter popup can cover the middle. Accepting the banner matters too, because that's what makes embedded maps and videos load.
  • Chat bubbles. One widget in the corner turns up in every capture of the site.
  • Lazy-loaded images. Images further down the page don't load until you scroll to them, so a page captured without scrolling comes back with empty rectangles.
  • Entrance animations. Page builders like Elementor hide sections until they scroll into view. If that never triggers, the section is still there but invisible, and the capture has a hole in it.
  • Sticky headers. If the page hasn't settled back at the top when the shot is taken, a fixed header lands partway down the image with the content sliced behind it.
  • Rate limits. Request pages too quickly and some sites answer with an error page, which captures like any other page and is easy to miss in a folder of forty.
  • Coming-soon pages. A staging site in maintenance mode shows the same placeholder at every address, so every capture succeeds and none of them is the site.

Each one takes a few lines of code to handle. The slow part is finding out about them.

If the site has no sitemap

Plenty of small sites don't publish one. In SiteHaul, open Advanced, choose Capture a list of URLs instead and paste the addresses one per line. The rest works the same way.

Questions

How do I find a website's sitemap?

Check /robots.txt for a line starting Sitemap:, which gives the address. If there isn't one, try /sitemap.xml, /sitemap_index.xml and, on WordPress, /wp-sitemap.xml. SiteHaul checks all of these for you when you enter a domain.

What if the site doesn't have a sitemap?

Make a list of the URLs you want, one per line. In SiteHaul, open Advanced, choose Capture a list of URLs instead, and paste them in. A list is also the way to capture pages that are deliberately left out of the sitemap.

Can I capture only some of the pages?

Yes. SiteHaul groups the pages by type before capturing, so you can untick all the blog posts or all the product pages at once, or pick pages one by one.

How many pages can I capture at once?

Up to 500 in one SiteHaul run, at desktop and mobile sizes. The free plan covers ten pages a month, and a page counts once whether you capture one size or both.

What sizes are the screenshots?

Desktop is captured at 1440 pixels wide. Mobile is 390 pixels wide, captured at double resolution so text stays sharp on a phone-sized image. Both are full length, from the top of the page to the bottom.

Try it on a site you know

10 pages a month free, which is enough to try it on a real site. No account, nothing uploaded.

Download for Mac

Apple silicon · macOS 12 or later · Notarized by Apple.

See everything SiteHaul does →