Skip to content

mevistoswe/PageSnapper

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

4 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

.NET License

PageSnapper

PageSnapper is a lightweight website screenshot API built with ASP.NET Core and Playwright.

It captures high-quality screenshots of public websites and returns them as PNG images.

Features include desktop/mobile rendering, full-page capture, optional cookie-consent cleanup, API key authentication, caller allowlists and SSRF protection.

The project was originally extracted from a larger production system and turned into a standalone service.


Live demo

A public demo instance is available:

https://pagesnapper-demo.mevisto.se/swagger

The demo instance is rate limited and intended for testing only.


Screenshot

Example screenshot generated by PageSnapper:

Example screenshot


Features

  • PNG website screenshots
  • Desktop and mobile rendering
  • Viewport or full-page capture
  • Optional cookie consent cleanup (clean=true)
  • API key authentication
  • Caller allowlist using Origin / Referer
  • SSRF protection for localhost/private networks
  • Basic in-memory rate limiting
  • Retry logic for unstable pages
  • Swagger API documentation
  • /health endpoint
  • CLI client for quick screenshot capture

API Endpoint

GET /api/screenshot


Query parameters

Parameter Required Description
url yes Target URL
mode no desktop or mobile
capture no viewport or fullpage
clean no true attempts to remove cookie banners

Example request

https://pagesnapper.example.com/api/screenshot?url=https://example.com&mode=desktop&capture=viewport&clean=true


Example using curl

curl "https://localhost:5001/api/screenshot?url=https://example.com&mode=desktop&capture=viewport&clean=true" --output screenshot.png

With API key:

curl -H "X-Api-Key: your-api-key" "https://localhost:5001/api/screenshot?url=https://example.com" --output screenshot.png


CLI Client

A small CLI tool is included for quickly capturing screenshots from the command line.

Example:

dotnet run --project src/PageSnapper.Cli --url https://example.com --mode desktop --output shot.png

Options:

Option Description
--url Target website
--mode desktop or mobile
--capture viewport or fullpage
--clean enable cookie banner cleanup
--output output filename

Architecture

Client │ │ HTTP request ▼ PageSnapper API │ │ validates request │ (API key / caller allowlist) ▼ URL validation (SSRF protection) │ ▼ Playwright browser │ │ renders page │ optionally removes cookie banners ▼ PNG screenshot │ ▼ Returned to client


Run locally

dotnet restore dotnet build dotnet run

Open Swagger:

https://localhost:5001/swagger

Health check:

https://localhost:5001/health


Install Playwright browser

After restoring the project you must install Chromium once:

playwright install chromium

If that command is not available:

dotnet tool install --global Microsoft.Playwright.CLI playwright install


IIS deployment

  1. Publish the API project

dotnet publish src/PageSnapper.Api/PageSnapper.Api.csproj -c Release -o .\publish\PageSnapper.Api

  1. Create an IIS site pointing to the published folder
  2. Use an Application Pool with No Managed Code
  3. Install the ASP.NET Core Hosting Bundle on the server
  4. Install Playwright browsers on the server
  5. Configure appsettings.json
  6. Verify /swagger and /health

Configuration example

{ "ScreenshotSecurity": { "Enabled": true, "ApiKeyHeaderName": "X-Api-Key", "ApiKeys": [ { "Name": "prod", "Key": "replace-this", "Scopes": [ "png" ] } ], "AllowedCallers": [ "localhost", "*.example.com" ], "RequestsPerMinute": 60 } }


Security model

A request is allowed when one of the following is true:

  1. A valid API key is provided
  2. The caller host is present in AllowedCallers

Caller hosts are validated using the Origin and Referer headers.

The target URL is validated to block:

  • localhost
  • loopback
  • private network ranges
  • link-local addresses

This prevents common SSRF attack vectors.


Notes

  • Full-page screenshots can be large and slower than viewport screenshots.
  • clean=true improves many pages but cannot guarantee perfect cookie-banner removal on all sites.
  • Some modern websites can be unstable in headless browsers; retry logic is included.
  • Caller allowlists typically apply to requests made from web pages, not direct navigation in the browser.

License

MIT License

About

Lightweight website screenshot API built with ASP.NET Core and Playwright.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages