Capture a full-page screenshot, long screenshot

Use when the user asks to capture a full-page screenshot, long screenshot, or complete page capture of a web page. Handles SPA scroll containers, lazy-loaded images, and very tall pages via Chrome DevTools Protocol with zero external…
---
name: "full-page-screenshot"
description: "Use when the user asks to capture a full-page screenshot, long screenshot, or complete page capture of a web page. Handles SPA scroll containers, lazy-loaded images, and very tall pages via Chrome DevTools Protocol with zero external dependencies."
---
# Full Page Screenshot
Capture a full-page screenshot of any web page via Chrome DevTools Protocol. Produces a single PNG that includes all content — even portions that require scrolling. Zero external dependencies beyond Node.js 22+ and Chrome with remote debugging enabled.
## Prerequisites
- **Node.js 22+** (uses built-in `WebSocket`)
- **Chrome/Chromium** with remote debugging enabled
Check environment readiness:
```bash
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --checkOverview
Capture a full-page screenshot of any web page via Chrome DevTools Protocol. Produces a single PNG that includes all content — even portions that require scrolling. Zero external dependencies beyond Node.js 22+ and Chrome with remote debugging enabled.
Manual install (npx, ZIP)
npx skills add alirezarezvani/claude-skills --skill full-page-screenshot -g -a claude-codemkdir -p ~/.claude/skills && curl -sL https://codeload.github.com/alirezarezvani/claude-skills/tar.gz/19392f7a0826 \
| tar -xz -C ~/.claude/skills --strip-components=3 claude-skills-19392f7a0826/engineering/skills/full-page-screenshotNew-Item -ItemType Directory -Force "$HOME\.claude\skills" | Out-Null; Invoke-WebRequest "https://m.agentalley.io/zip/11bc86fab1e746fbd969/full-page-screenshot.zip" -OutFile "$env:TEMP\full-page-screenshot.zip"; Expand-Archive "$env:TEMP\full-page-screenshot.zip" -DestinationPath "$HOME\.claude\skills" -ForceConnects with Agent Alley MCP · agentalley.io/mcp
Files included
SKILL.md5.4 KBscripts/1 file · 35.1 KB
Read the files here
alirezarezvani/
Shared references2SKILL.md reads these from elsewhere in the repo. Not in the ZIP.
- SKILL.mdengineering/skills/browser-automation/13.5 KB
- SKILL.mdengineering/skills/performance-profiler/2.7 KB
Show the full text124 lines
Full Page Screenshot
Capture a full-page screenshot of any web page via Chrome DevTools Protocol. Produces a single PNG that includes all content — even portions that require scrolling. Zero external dependencies beyond Node.js 22+ and Chrome with remote debugging enabled.
Prerequisites
- Node.js 22+ (uses built-in
WebSocket) - Chrome/Chromium with remote debugging enabled
Check environment readiness:
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --check
If Chrome check fails, instruct user to open chrome://inspect/#remote-debugging and enable "Allow remote debugging for this browser instance".
Workflow
Option A: Screenshot an already-open tab (recommended for authenticated pages)
- List available tabs:
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --list
- Identify the target by title/URL, then capture:
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" <targetId> /tmp/screenshot.png --width 1200 --dpr 1
Option B: Screenshot a URL (opens a background tab, captures, closes)
node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --url "https://example.com" /tmp/screenshot.png --width 1200 --dpr 1 --wait 15000
Note:
--urlmode creates a background tab. Pages requiring authentication (SSO, login walls) should use Option A instead.
Parameters
| Parameter | Description | Default |
|---|---|---|
output |
Output PNG file path | /tmp/screenshot.png |
--width |
Viewport width in CSS pixels (articles: 1200, dashboards: 1440-1920) | 1200 |
--dpr |
Device pixel ratio (2 = Retina, but 4x file size) | 1 |
--wait |
Page load timeout in ms (--url mode only) |
15000 |
--css |
Custom CSS to inject before capture (e.g., hide elements) | — |
Verify Output
# macOS
sips -g pixelWidth -g pixelHeight /tmp/screenshot.png
# Linux
file /tmp/screenshot.png
Core Capabilities
SPA scroll container expansion — Detects
overflow-y: auto/scrollcontainers, scrolls through them to trigger lazy-loading, then removes overflow constraints (including Tailwindh-[calc(...)]) so all content renders in a single pass.DOM stability detection — After
readyState=complete, monitors DOM element count until it stabilizes. This ensures SPA frameworks finish rendering dynamic content.Lazy-load triggering — Scrolls the viewport incrementally to fire
IntersectionObservercallbacks, then waits for all<img>elements to complete loading.Tiled capture for very tall pages — Pages exceeding 16,000px are captured in 8,000px tiles and automatically stitched using Python PIL. Falls back to saving tiles separately if PIL is unavailable.
Auto-discovery of Chrome — Reads
DevToolsActivePortfile to find the debugging port. Falls back to probing ports 9222, 9229, 9333.CDP Proxy fallback — When a CDP proxy holds the browser WebSocket, the script falls back to proxy API endpoints (
/eval,/screenshot,/scroll) for capture.
How It Works
1. Discover Chrome debugging port
2. Connect via WebSocket (CDP)
3. Attach to target / create background tab
4. Set viewport width via Emulation domain
5. Wait: readyState + DOM stability
6. Detect & expand scroll containers
7. Scroll through page (trigger lazy-load)
8. Wait for images to complete
9. Measure final content height
10. Page.captureScreenshot (or tiled capture)
11. Stitch tiles if needed (PIL)
12. Restore viewport, detach, clean up
Anti-Patterns
| Do NOT | Do instead |
|---|---|
Use --dpr 2 on pages > 10,000px tall |
Use --dpr 1 to avoid Chrome memory issues |
Use --url for authenticated/SSO pages |
Use --list + targetId on a tab where user is logged in |
Set --wait below 5000 for SPAs |
SPAs need time to fetch data and render; use 10000-15000 |
Capture without checking --check first |
Always verify Chrome debugging is available |
| Hardcode viewport widths for all pages | Use 1200 for articles, 1440+ for dashboards/tables |
| Skip output verification | Always verify with sips or file command after capture |
Troubleshooting
| Symptom | Cause | Fix |
|---|---|---|
| "Cannot find Chrome debugging port" | Remote debugging not enabled | Open chrome://inspect/#remote-debugging, enable it |
| "WebSocket connection timeout" | CDP proxy holding the connection | Script auto-falls back to proxy API |
| Blank/white screenshot | Page not loaded yet | Increase --wait value |
| Truncated at bottom | Scroll container not expanded | Script handles this automatically; file an issue if it persists |
| Out of memory | Very tall page + high DPR | Reduce --dpr to 1 and/or reduce --width |
| "PIL not available for stitching" | Python Pillow not installed | Install with pip3 install Pillow or accept separate tile files |
Cross-References
engineering/browser-automation— General browser automation patterns via CDP/Playwrightengineering/performance-profiler— Performance analysis that may complement visual captures
| 1 | |
| 2 | name "full-page-screenshot" |
| 3 | description "Use when the user asks to capture a full-page screenshot, long screenshot, or complete page capture of a web page. Handles SPA scroll containers, lazy-loaded images, and very tall pages via Chrome DevTools Protocol with zero external dependencies." |
| 4 | |
| 5 | |
| 6 | # Full Page Screenshot |
| 7 | |
| 8 | Capture a full-page screenshot of any web page via Chrome DevTools Protocol. Produces a single PNG that includes all content — even portions that require scrolling. Zero external dependencies beyond Node.js 22+ and Chrome with remote debugging enabled. |
| 9 | |
| 10 | ## Prerequisites |
| 11 | |
| 12 | **Node.js 22+** (uses built-in `WebSocket`) |
| 13 | **Chrome/Chromium** with remote debugging enabled |
| 14 | |
| 15 | Check environment readiness: |
| 16 | |
| 17 | |
| 18 | node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --check |
| 19 | |
| 20 | |
| 21 | If Chrome check fails, instruct user to open `chrome://inspect/#remote-debugging` and enable **"Allow remote debugging for this browser instance"**. |
| 22 | |
| 23 | ## Workflow |
| 24 | |
| 25 | ### Option A: Screenshot an already-open tab (recommended for authenticated pages) |
| 26 | |
| 27 | List available tabs: |
| 28 | |
| 29 | |
| 30 | node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --list |
| 31 | |
| 32 | |
| 33 | Identify the target by title/URL, then capture: |
| 34 | |
| 35 | |
| 36 | node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" <targetId> /tmp/screenshot.png --width 1200 --dpr 1 |
| 37 | |
| 38 | |
| 39 | ### Option B: Screenshot a URL (opens a background tab, captures, closes) |
| 40 | |
| 41 | |
| 42 | node "${SKILL_DIR}/scripts/full-page-screenshot.mjs" --url "https://example.com" /tmp/screenshot.png --width 1200 --dpr 1 --wait 15000 |
| 43 | |
| 44 | |
| 45 | > **Note:** `--url` mode creates a background tab. Pages requiring authentication (SSO, login walls) should use Option A instead. |
| 46 | |
| 47 | ### Parameters |
| 48 | |
| 49 | | Parameter | Description | Default | |
| 50 | |-----------|-------------|---------| |
| 51 | | `output` | Output PNG file path | `/tmp/screenshot.png` | |
| 52 | | `--width` | Viewport width in CSS pixels (articles: 1200, dashboards: 1440-1920) | 1200 | |
| 53 | | `--dpr` | Device pixel ratio (2 = Retina, but 4x file size) | 1 | |
| 54 | | `--wait` | Page load timeout in ms (`--url` mode only) | 15000 | |
| 55 | | `--css` | Custom CSS to inject before capture (e.g., hide elements) | — | |
| 56 | |
| 57 | ### Verify Output |
| 58 | |
| 59 | |
| 60 | # macOS |
| 61 | sips -g pixelWidth -g pixelHeight /tmp/screenshot.png |
| 62 | |
| 63 | # Linux |
| 64 | file /tmp/screenshot.png |
| 65 | |
| 66 | |
| 67 | ## Core Capabilities |
| 68 | |
| 69 | **SPA scroll container expansion** — Detects `overflow-y: auto/scroll` containers, scrolls through them to trigger lazy-loading, then removes overflow constraints (including Tailwind `h-[calc(...)]`) so all content renders in a single pass. |
| 70 | |
| 71 | **DOM stability detection** — After `readyState=complete`, monitors DOM element count until it stabilizes. This ensures SPA frameworks finish rendering dynamic content. |
| 72 | |
| 73 | **Lazy-load triggering** — Scrolls the viewport incrementally to fire `IntersectionObserver` callbacks, then waits for all `<img>` elements to complete loading. |
| 74 | |
| 75 | **Tiled capture for very tall pages** — Pages exceeding 16,000px are captured in 8,000px tiles and automatically stitched using Python PIL. Falls back to saving tiles separately if PIL is unavailable. |
| 76 | |
| 77 | **Auto-discovery of Chrome** — Reads `DevToolsActivePort` file to find the debugging port. Falls back to probing ports 9222, 9229, 9333. |
| 78 | |
| 79 | **CDP Proxy fallback** — When a CDP proxy holds the browser WebSocket, the script falls back to proxy API endpoints (`/eval`, `/screenshot`, `/scroll`) for capture. |
| 80 | |
| 81 | ## How It Works |
| 82 | |
| 83 | |
| 84 | 1. Discover Chrome debugging port |
| 85 | 2. Connect via WebSocket (CDP) |
| 86 | 3. Attach to target / create background tab |
| 87 | 4. Set viewport width via Emulation domain |
| 88 | 5. Wait: readyState + DOM stability |
| 89 | 6. Detect & expand scroll containers |
| 90 | 7. Scroll through page (trigger lazy-load) |
| 91 | 8. Wait for images to complete |
| 92 | 9. Measure final content height |
| 93 | 10. Page.captureScreenshot (or tiled capture) |
| 94 | 11. Stitch tiles if needed (PIL) |
| 95 | 12. Restore viewport, detach, clean up |
| 96 | |
| 97 | |
| 98 | ## Anti-Patterns |
| 99 | |
| 100 | | Do NOT | Do instead | |
| 101 | |--------|-----------| |
| 102 | | Use `--dpr 2` on pages > 10,000px tall | Use `--dpr 1` to avoid Chrome memory issues | |
| 103 | | Use `--url` for authenticated/SSO pages | Use `--list` + targetId on a tab where user is logged in | |
| 104 | | Set `--wait` below 5000 for SPAs | SPAs need time to fetch data and render; use 10000-15000 | |
| 105 | | Capture without checking `--check` first | Always verify Chrome debugging is available | |
| 106 | | Hardcode viewport widths for all pages | Use 1200 for articles, 1440+ for dashboards/tables | |
| 107 | | Skip output verification | Always verify with `sips` or `file` command after capture | |
| 108 | |
| 109 | ## Troubleshooting |
| 110 | |
| 111 | | Symptom | Cause | Fix | |
| 112 | |---------|-------|-----| |
| 113 | | "Cannot find Chrome debugging port" | Remote debugging not enabled | Open `chrome://inspect/#remote-debugging`, enable it | |
| 114 | | "WebSocket connection timeout" | CDP proxy holding the connection | Script auto-falls back to proxy API | |
| 115 | | Blank/white screenshot | Page not loaded yet | Increase `--wait` value | |
| 116 | | Truncated at bottom | Scroll container not expanded | Script handles this automatically; file an issue if it persists | |
| 117 | | Out of memory | Very tall page + high DPR | Reduce `--dpr` to 1 and/or reduce `--width` | |
| 118 | | "PIL not available for stitching" | Python Pillow not installed | Install with `pip3 install Pillow` or accept separate tile files | |
| 119 | |
| 120 | ## Cross-References |
| 121 | |
| 122 | [`engineering/browser-automation`] — General browser automation patterns via CDP/Playwright |
| 123 | [`engineering/performance-profiler`] — Performance analysis that may complement visual captures |
| 124 |
Details
- Updated
- Aug 30, 2026
- License
- MIT
- Stars on the repo
- ★ 26,349
- Checked
- Source
- alirezarezvani/claude-skills ↗
- Creator
- alirezarezvani · 363 listings
Similar skills
See all →
SkillExtract text, tables, metadataXberg Document Extraction
SkillMove code from one implementation to another functionCode migration
SkillManages Ahrefs API usage in Python using ahrefs-python
MCPDocx LLM translatoradeu
SkillCreate an Amazon-compliant white-background main imageAmazon White-Background Main Image · 亚马逊白底主图
MCPOfficial monorepo of SDKs, CLISendmux sdkMore from alirezarezvani
SkillResume a paused experiment/ar:ar-resume — Resume Experiment
SkillShow experiment dashboard with results, active loops/ar:ar-status — Experiment Dashboard
SkillStart an autonomous experiment loop with user-selected/ar:loop — Autonomous Experiment Loop
SkillRun a single experiment iteration/ar:run — Single Experiment Iteration
SkillSet up a new autoresearch experiment interactively/ar:setup — Create New Experiment
Skill/cs:boardroom <brief/cs:boardroom — Multi-Role Boardroom Deliberation