Skip to content

Repository files navigation

Site Snapshotter

Archive any website as a ZIP of full-page screenshots — every page discovered, captured exactly as your browser serves it, stamped with URL + capture time, and packed with a JSON manifest, a browsable gallery, and optional PDF book and contact-sheet poster.

Built for designers archiving site designs, QA teams documenting regressions, and anyone who needs a verifiable, point-in-time record of a website — including pages behind a login.

Popup — enter a site, pick a preset, start the capture Dashboard — live contact sheet of a real capture run

Install

From a release (no build tools needed)

  1. Download site-snapshotter-vX.Y.Z.zip from the Releases page and unzip it.
  2. In Chrome: chrome://extensions → enable Developer modeLoad unpacked → select the unzipped folder.

From source

git clone https://github.com/mantisdotdev/site-snapshotter.git
cd site-snapshotter
npm install
npm run build

Then load dist/ as above (chrome://extensions → Developer mode → Load unpacked).

Use

  1. Click the toolbar icon, enter a site URL (it prefills from the active tab).
  2. Pick a preset (Design archive / Compliance / QA audit) or set options individually:
    • Scope — whole site (sitemap + crawl) or home page + nav bar pages only; optionally review/prune the discovered list before capturing.
    • Variants — tablet and mobile viewports, dark + light color-scheme shots, retina (2×).
    • Extras — MHTML page archives, a merged PDF site book (cover + contents), a contact-sheet poster PNG.
    • Report data — per-page issues (console errors, failed requests, redirects) and SEO metadata (h1, description, og:image, canonical).
    • Run-to-run diffing — each run pixel-compares against the previous run of the same site (baseline kept in IndexedDB): cards get no change / Δ 3.2% / new page chips, the summary counts changes, and manifest.json records per-page diff status.
  3. Set the page limit (default 50), settle wait, and page-prep toggles.
  4. Start capture opens a dashboard tab — a contact sheet that fills in live. After the run, any frame has a retake button.
  5. When the run finishes (or you cancel), Download ZIP.

The ZIP contains (extras only when enabled):

shots/001-index.png             # full-page PNGs, provenance banner on top
shots/001-index--mobile-dark.png  # variant shots, when enabled
pages-mhtml/001-index.mhtml     # MHTML archives
manifest.json                   # per-page URL, title, status, shots, issues, SEO data
index.html                      # standalone dark gallery of the whole run
poster.png                      # contact-sheet poster
site-book.pdf                   # merged PDF book

Privacy and permissions

Everything stays on your machine. Captures are written to a ZIP you save locally; run history and diff baselines live in your browser's local storage. There is no server, no analytics, no telemetry, no network upload of any kind — the only outbound requests are the page fetches needed to crawl the site you asked for.

The extension requests broad permissions because of what it does; none is used for anything else:

Permission Why it's needed
debugger Drives a background tab over the DevTools Protocol to take pixel-perfect full-page screenshots in one shot (no stitching seams). This is why Chrome shows an "is debugging this browser" bar during a run.
<all_urls> (host access) You can point it at any site; the crawl fetches pages and sitemaps from the target origin only.
downloads Saves the ZIP via Chrome's download manager (always with a Save-As prompt).
storage, unlimitedStorage Remembers your settings and keeps screenshot baselines for run-to-run diffing.

Because captures run in your browser session, logged-in pages are captured as you see them — ZIPs can contain private content; treat them as sensitive.

How it works

  • Discovery — whole-site scope reads robots.txt / sitemap.xml (incl. one level of sitemap index), falling back to a same-host breadth-first link crawl. Nav scope loads the home page in the worker tab and collects links from its rendered <nav> / <header> / role="navigation" landmarks (so JS-rendered menus work). Trailing-slash and #fragment variants are deduped; query strings are kept as distinct pages.
  • Capture — a pinned background worker tab is driven over the Chrome DevTools Protocol (chrome.debugger): navigate → wait for load + settle → freeze CSS animations → dismiss cookie banners → auto-scroll for lazy-load → hide chat widgets → one-shot Page.captureScreenshot with captureBeyondViewport (no stitching).
  • Variants — viewports via Emulation.setDeviceMetricsOverride, dark/light via emulated prefers-color-scheme, retina via capture scale. Each page loads once; variants are shot back-to-back.
  • Provenance — each PNG gets a banner with the URL and local capture time; the same data lands in manifest.json. Run summaries (no images) are kept in chrome.storage.local; the latest run's base shots stay in IndexedDB as the diffing baseline for the next run.

Notes and limits

  • Chrome shows an "is debugging this browser" bar during a run — that's the price of pixel-perfect one-shot captures. It disappears when the run ends.
  • Page height is capped at 16,000 CSS px; width at 3,000 (taller pages are marked truncated).
  • Closing the dashboard tab stops the run.

Dev

npm run typecheck   # tsc --noEmit
npm run build       # esbuild → dist/
npm run watch       # rebuild on change (reload the extension in Chrome after)

Full gate: npm run typecheck && npm run build && node test/e2e.mjs. The end-to-end suite drives the built extension in a real Chromium via Playwright and byte-verifies the ZIP output (see its header for setup). Icons regenerate with tools/gen-icons.mjs.

Open items live in BACKLOG.md; architectural decisions in docs/DECISIONS.md.

License

MIT

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages