screenshot-local
Original:🇺🇸 English
Translated
Use when capturing screenshots of local projects, documenting web app UI, taking screenshots of localhost dev servers, or generating images for READMEs and docs. Use when asked to "screenshot my app", "capture the UI", "take a screenshot of localhost", "generate screenshots for docs", "batch screenshot my pages", or "set up shot-scraper".
2installs
Sourceantjanus/skillbox
Added on
NPX Install
npx skill4agent add antjanus/skillbox screenshot-localTags
Translated version includes tags in frontmatterSKILL.md Content
View Translation Comparison →Screenshot Local - Capture Project Screenshots with shot-scraper
Overview
Capture screenshots of local development projects using shot-scraper installed globally via pipx. Turn localhost URLs and local HTML files into PNGs, JPEGs, and PDFs for documentation, READMEs, and design reviews.
Core principle: Screenshots should be reproducible from a single command or YAML config, not manual screen captures. Version-control your screenshot configs alongside your code.
When to Use
Use this skill when:
- Capturing screenshots of a local dev server for docs or README
- Generating screenshots of multiple pages/states in batch
- Documenting UI changes or new features visually
- Creating before/after comparisons during refactoring
- Automating screenshot generation in CI/CD
Avoid when:
- Recording terminal/CLI output (use with VHS instead)
record-tui - Capturing non-web content (use native screenshot tools)
- Scraping third-party websites (shot-scraper can do it, but this skill focuses on local projects)
Prerequisites
Install shot-scraper globally via pipx:
bash
# Install pipx if needed
brew install pipx # macOS
# or: apt install pipx / pip install pipx
# Install shot-scraper globally
pipx install shot-scraper
# Install the browser engine (Chromium by default)
shot-scraper installVerify:
shot-scraper --versionAlternative browsers:
bash
shot-scraper install -b firefox
shot-scraper install -b webkitPhase 1: Plan the Screenshots
Before capturing, answer these questions:
- What are you capturing? — localhost URL, local HTML file, or built static site
- Which pages/states? — Single page, multiple routes, or specific UI states
- What dimensions? — Match your target display context
- Any interaction needed? — Click buttons, fill forms, dismiss modals before capture
Recommended dimensions by use case:
| Use Case | Width | Height | Format |
|---|---|---|---|
| README hero image | 1280 | 800 | PNG |
| Docs screenshot | 1200 | auto | PNG |
| Social/OG image | 1200 | 630 | PNG |
| Mobile viewport | 375 | 812 | PNG |
| Tablet viewport | 768 | 1024 | PNG |
| Full page capture | 1280 | (omit) | PNG |
Phase 2: Capture Screenshots
Single Screenshot
Capture a localhost page:
bash
shot-scraper http://localhost:3000 -o homepage.pngCapture a local HTML file:
bash
shot-scraper index.html -o preview.pngWith custom dimensions:
bash
shot-scraper http://localhost:3000 -w 1200 -h 800 -o homepage.pngRetina (2x resolution):
bash
shot-scraper http://localhost:3000 --retina -o homepage-retina.pngCapture a specific element:
bash
shot-scraper http://localhost:3000 -s ".hero-section" -o hero.png
shot-scraper http://localhost:3000 -s "#main-nav" --padding 10 -o nav.pngWait for dynamic content:
bash
# Wait fixed time (ms)
shot-scraper http://localhost:3000 --wait 2000 -o page.png
# Wait for JS condition
shot-scraper http://localhost:3000 --wait-for "document.querySelector('.loaded')" -o page.pngExecute JS before capture (dismiss modals, set state):
bash
shot-scraper http://localhost:3000 \
-j "document.querySelector('.cookie-banner')?.remove()" \
-o clean-homepage.pngEssential Options
| Flag | Example | Purpose |
|---|---|---|
| | Output filename |
| | Viewport width (default: 1280) |
| | Viewport height (omit for full page) |
| | CSS selector to capture |
| | All matching elements |
| | Padding around selector (px) |
| | 2x device pixel ratio |
| | Save as JPEG with quality |
| | Wait ms after page load |
| | Wait until JS returns true |
| | Execute JS before screenshot |
| | Browser (chromium/firefox/webkit) |
| | Transparent background (PNG) |
| | Failure timeout (ms) |
For the complete flag reference, see Command Reference.
Batch Screenshots with YAML
Create a for capturing multiple pages:
shots.ymlyaml
# shots.yml
- url: http://localhost:3000
output: screenshots/homepage.png
width: 1280
height: 800
- url: http://localhost:3000/about
output: screenshots/about.png
width: 1280
- url: http://localhost:3000/dashboard
output: screenshots/dashboard.png
width: 1280
height: 900
wait: 2000
javascript: |
document.querySelector('.loading-spinner')?.remove()
- url: http://localhost:3000
output: screenshots/mobile-home.png
width: 375
height: 812Run the batch:
bash
shot-scraper multi shots.ymlAdvanced YAML Keys
yaml
- url: http://localhost:3000/form
output: screenshots/form-filled.png
width: 1200
javascript: |
document.querySelector('#name').value = 'Jane Doe';
document.querySelector('#email').value = 'jane@example.com';
wait: 500
selector: ".form-container"
padding: 20
retina: trueSupported YAML keys: , , , , , , , , , , , , , ,
urloutputwidthheightqualitywaitwait_forselectorselectorsselector_allpaddingjavascriptjs_selectorretinaomit_backgroundPhase 3: Smart Config Generation
When asked to generate a screenshot config for a project, follow this process:
Step 1: Analyze the Project
Read the project to understand:
- Routes/pages — Check router config, page files, or navigation
- Key UI states — Loading, empty, populated, error states
- Important components — Hero sections, dashboards, forms
- Port — What port does the dev server run on
Step 2: Generate shots.yml
Build a YAML config covering the project's key screens:
bash
# Validate by running
shot-scraper multi shots.ymlStep 3: Iterate
Review screenshots, adjust timing and selectors, re-run.
Phase 4: Optimize Output
File Size Reduction
Use JPEG for photos/complex UIs:
bash
shot-scraper http://localhost:3000 --quality 85 -o page.jpgUse PNG for UI with text/sharp edges (default).
Transparent backgrounds (for overlaying on docs):
bash
shot-scraper http://localhost:3000 -s ".component" --omit-background -o widget.pngConsistency Tips
- Always set explicit — default 1280 is fine but be intentional
width - Omit for full-page captures, set it for fixed viewport
height - Use for README images viewed on high-DPI screens
--retina - Add for SPAs that hydrate client-side
--wait - Use to dismiss cookie banners, tooltips, or modals
javascript - Use +
selectorto capture specific components cleanlypadding
Phase 5: CI/CD Integration
GitHub Actions
yaml
name: Update Screenshots
on:
push:
branches: [main]
paths: ["src/**", "shots.yml"]
jobs:
screenshots:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup Python
uses: actions/setup-python@v5
with:
python-version: "3.12"
- name: Install shot-scraper
run: |
pip install shot-scraper
shot-scraper install
- name: Capture screenshots
run: |
npm ci && npm run dev &
sleep 5
shot-scraper multi shots.yml
- name: Commit updated screenshots
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: "docs: update screenshots"
file_pattern: "screenshots/*.png"Tip: Use the key in YAML to auto-start a dev server — see Templates.
serverExamples
Good: Well-Structured Screenshot Config
<Good>yaml
# shots.yml — explicit dimensions, proper waits, organized output
- url: http://localhost:3000
output: screenshots/homepage.png
width: 1280
height: 800
- url: http://localhost:3000/dashboard
output: screenshots/dashboard.png
width: 1280
height: 900
wait: 2000
javascript: |
document.querySelector('.toast-notification')?.remove()
- url: http://localhost:3000/settings
output: screenshots/settings.png
width: 1280
selector: ".settings-panel"
padding: 20
- url: http://localhost:3000
output: screenshots/mobile-home.png
width: 375
height: 812Bad: Common Mistakes
<Bad>yaml
# No output specified — shot-scraper auto-names from URL, messy results
- url: http://localhost:3000
# No width — relies on default, inconsistent across machines
- url: http://localhost:3000/about
output: about.png
# No wait for SPA — captures loading spinner instead of content
- url: http://localhost:3000/dashboard
output: dashboard.png
# Screenshot directory not organized
- url: http://localhost:3000/settings
output: settings.pngGood: Capturing Specific Components
<Good>bash
# Hero section with padding for breathing room
shot-scraper http://localhost:3000 -s ".hero" -p 20 -o docs/hero.png
# Navigation in retina for crisp text
shot-scraper http://localhost:3000 -s "nav" --retina -o docs/nav.png
# Form with pre-filled data via JS
shot-scraper http://localhost:3000/contact \
-j "document.querySelector('#name').value = 'Jane Doe'" \
-s ".contact-form" -p 10 -o docs/form.pngBad: Component Capture Anti-Patterns
<Bad>bash
# No selector — captures entire page when you only need one section
shot-scraper http://localhost:3000 -o hero.png
# No padding — element cropped tight, looks cramped in docs
shot-scraper http://localhost:3000 -s ".hero" -o hero.png
# No wait — dynamic component hasn't rendered yet
shot-scraper http://localhost:3000 -s ".chart" -o chart.pngTroubleshooting
Problem: Screenshot shows blank page or loading spinner
Cause: SPA hasn't hydrated or async data hasn't loaded.
Solution:
bash
# Fixed wait
shot-scraper http://localhost:3000 --wait 3000 -o page.png
# Wait for specific element
shot-scraper http://localhost:3000 --wait-for "document.querySelector('.content')" -o page.pngProblem: "Connection refused" on localhost
Cause: Dev server isn't running or is on a different port.
Solution:
- Start your dev server first:
npm run dev & - Verify the port:
curl -I http://localhost:3000 - Or use the key in YAML to auto-start it
server
Problem: Screenshot dimensions don't match expectations
Cause: Height omitted (captures full page) or retina not accounted for.
Solution:
- Set explicit for fixed viewport
-h - Omit intentionally for full-page capture
-h - doubles pixel dimensions (1280w becomes 2560px image)
--retina
Problem: shot-scraper command not found
Cause: Not installed or pipx PATH not configured.
Solution:
bash
pipx install shot-scraper
pipx ensurepath # Add pipx bin to PATH
shot-scraper install # Install browser engineProblem: Elements missing from screenshot
Cause: CSS selector wrong, element behind a modal, or lazy-loaded content.
Solution:
bash
# Use --interactive to debug visually
shot-scraper http://localhost:3000 -i
# Use --devtools for inspector
shot-scraper http://localhost:3000 --devtoolsIntegration
This skill pairs with:
- record-tui — For terminal app recordings (use VHS for CLIs, shot-scraper for web UIs)
- track-session — Track screenshot iteration progress
- git-worktree — Compare screenshots across branches
Useful alongside:
- shot-scraper — The screenshot tool
- shot-scraper-template — GitHub Actions template
- pipx — Global Python app installer
Quick Reference
bash
# Single screenshot
shot-scraper http://localhost:3000 -o page.png
# With dimensions
shot-scraper http://localhost:3000 -w 1280 -h 800 -o page.png
# Specific element
shot-scraper http://localhost:3000 -s ".hero" -p 10 -o hero.png
# Retina
shot-scraper http://localhost:3000 --retina -o page@2x.png
# Local HTML file
shot-scraper index.html -o preview.png
# Batch from YAML
shot-scraper multi shots.yml
# Interactive debugging
shot-scraper http://localhost:3000 -i
# PDF export
shot-scraper pdf http://localhost:3000 -o page.pdfDeep Reference
For detailed guides, load these files when needed:
- Command Reference — All shot-scraper commands, flags, and subcommands
- Templates — Copy-paste YAML configs for common project types
Only load these when specifically needed to save context.
References
- shot-scraper — Official repository
- shot-scraper documentation — Full docs
- shot-scraper-template — GitHub Actions template
- pipx — Global Python app installer
- Simon Willison's blog — Author's posts on shot-scraper