Capture an Entire Web Page as an Image
Capture a full web page beyond the viewport with Edge, Firefox, iPhone, Chrome DevTools, Playwright, or ScreenshotNeo.
Short answer: use a full-page screenshot command, not a normal viewport capture. In Edge press Ctrl+Shift+S and choose Capture full page; in Firefox choose Save full page. For repeatable work, Playwright’s fullPage option captures the entire scrollable document. On iPhone, take a screenshot, choose Full Page, then save it as an image or PDF.
A full-page image includes content below the visible viewport. It is different from saving page source or a web archive, which preserve page data rather than a rendered image.
Choose the right capture method
| Situation | Best method | Output |
|---|---|---|
| API and no browser maintenance | ScreenshotNeo | PNG, JPEG, WebP, or PDF |
| One-off desktop capture | Edge or Firefox built-in Screenshot | Image file |
| Chrome debugging | DevTools full-page screenshot | Image file |
| iPhone or iPad | Screenshot preview → Full Page | Image or PDF |
| Repeatable scripts, CI, or many URLs | Playwright | PNG/JPEG/WebP bytes or file |
Browser methods
Microsoft Edge
- Open the page.
- Press Ctrl+Shift+S (or open Edge’s Screenshot command).
- Select Capture full page.
- Review the result and save or copy it.
Microsoft documents that Screenshot can capture a full page or a selected area. Labels and availability can vary by device, market, and browser version. See Microsoft’s Edge Screenshot guide.
Firefox
- Open the page and right-click it (or use the browser menu).
- Choose Take Screenshot.
- Choose Save full page.
- Save the generated image.
Firefox also offers visible, region, and element captures. Mozilla’s screenshot help documents these choices.
Chrome DevTools
- Open DevTools with F12 or Ctrl+Shift+I.
- Open the DevTools command menu and search for the screenshot commands.
- Choose the full-page capture command and save the image.
Chrome’s DevTools also supports node, mobile, and area captures. Menu names can change, so use the current command menu rather than relying on an older click path. Chrome for Developers’ screenshot tips explains the available techniques.
iPhone and iPad
- Take a normal screenshot.
- Tap its preview thumbnail.
- Select Full Page.
- Crop if needed, then save to Photos as an image or to Files as a PDF.
This workflow is documented in Apple’s iPhone guide. The Full Page option appears only in apps and pages that support it.
Safari on Mac: do not confuse saving with screenshotting
Safari’s documented Web Archive and Page Source commands save page data. They are not full-page screenshot images. If you need a rendered image, use DevTools, Playwright, or an image API instead. Apple’s Safari for Mac guide describes those save formats.
Automate full-page captures with Playwright
Playwright renders the page in a real browser and its full-page option covers the full scrollable page. Install the package and a browser, then run one of these examples. Playwright screenshot documentation.
JavaScript (Node.js)
import { chromium } from 'playwright';
const browser = await chromium.launch();
const page = await browser.newPage({ viewport: { width: 1440, height: 900 }, deviceScaleFactor: 1 });
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.screenshot({ path: 'page.png', fullPage: true, type: 'png' });
await browser.close();
Install with npm install playwright and then npx playwright install chromium.
Python
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
page = browser.new_page(viewport={"width": 1440, "height": 900}, device_scale_factor=1)
page.goto("https://example.com", wait_until="networkidle")
page.screenshot(path="page.png", full_page=True, type="png")
browser.close()
Install with pip install playwright and then playwright install chromium.
Wait for lazy content before stitching
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
await page.locator('main').waitFor();
await page.waitForTimeout(1000); // allow a lazy section to render
await page.screenshot({ path: 'complete.png', fullPage: true });
Use a selector wait when a specific component signals readiness. A fixed delay is a fallback; it is less reliable than waiting for a real condition.
Capture bytes instead of writing a file
const image = await page.screenshot({ fullPage: true, type: 'jpeg', quality: 85 });
// image is a Buffer; upload it to your object storage or HTTP endpoint.
Rendering controls that affect the result
- Viewport: set a deterministic width and height. Responsive breakpoints change both layout and page height.
- Device scale factor: increase it for sharper output, but expect larger files and more memory use.
- Format: PNG preserves text and transparency; JPEG is smaller for photographic pages; WebP often balances both.
- Animations: pause or disable CSS animations if a capture must be repeatable.
- Fonts: wait for
document.fonts.readywhen late-loading fonts alter line wrapping. - Lazy images: scroll through the page or wait for image elements before capture so below-the-fold assets load.
- Sticky headers: a fixed header may appear repeatedly or cover content. Hide it with CSS or capture the main element when appropriate.
- Very tall pages: split the document into sections if the browser or image viewer cannot handle one extremely large bitmap.
Common problems and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| Only the visible viewport is saved | Viewport screenshot command was used | Choose full-page mode or pass fullPage: true/full_page=True. |
| Bottom sections are blank | Lazy loading or intersection observers have not run | Scroll incrementally, wait for a known selector, then capture. |
| Fonts or layout jump | Web fonts loaded after capture started | Wait for document.fonts.ready and the page’s layout-ready signal. |
| Cookie banner, popup, or chat covers content | Overlay is part of the rendered page | Dismiss it manually, hide its selector in automation, or use ScreenshotNeo’s cleanup. |
| Capture times out | Never-ending requests or a slow origin | Use a bounded navigation timeout, wait for a selector instead of global network idle, and retry idempotently. |
| Images are missing | Blocked third-party resources, auth, or hotlink protection | Provide required cookies/headers, allow the resource, or capture after it finishes loading. |
| Text is blurry | Low device scale factor or JPEG compression | Raise the scale factor or use PNG/WebP. |
| File is too large | Huge dimensions or lossless encoding | Use JPEG/WebP, resize after capture, reduce scale, or segment the page. |
| Playwright browser is missing | Package installed without browser binaries | Run the appropriate playwright install command. |
Performance, reliability, and cost
Performance
Capture time is dominated by navigation, JavaScript, fonts, images, and any waiting policy. A fixed viewport does not make a full-page job cheap: the browser still lays out the entire scrollable document. Reuse a browser process for batches, create isolated contexts per site, block unnecessary analytics or video requests when policy allows, and avoid waiting for global network idle on pages with long-polling connections.
Reliability
- Use explicit timeouts and record the URL, viewport, browser version, and wait condition with each artifact.
- Retry transient navigation failures with backoff; do not blindly duplicate side-effecting interactions.
- Check that the output has nonzero dimensions and expected key content before publishing it.
- Respect robots, authentication, rate limits, and the site’s terms. Send credentials only to origins you trust.
Cost
Self-hosted Playwright costs the compute, storage, and maintenance of browsers and dependencies. Browser-native captures use the software you already have. An API trades that setup for per-capture pricing and operational limits; compare the cost of failed jobs, retries, and engineering time, not only the image request.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. It removes cookie and consent banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response identifies the result with X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients.
See the ScreenshotNeo API documentation for request details. This is a complete one-call capture:
cURL
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
const image = Buffer.from(await res.arrayBuffer());
When you need more control, ScreenshotNeo supports full-page capture with lazy images loaded, CSS element capture, dark mode, 12 device presets or any viewport, retina scale, custom CSS and JavaScript, click-before-capture, selector hiding, selector or delay or network-idle waits, request and resource blocking, custom headers/cookies/user agent/Authorization, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI spec. Parameter names used by other screenshot APIs also work, which simplifies migration.
Plans include 1,000 shots per month free with no card; paid plans start at $5 for 3,000 shots. Higher plans are $15 for 15,000, $39 for 60,000, $99 for 250,000, and $249 for 1,000,000; yearly billing gives two months free, and every feature is on every plan.
Create a free ScreenshotNeo account and start with 1,000 screenshots a month at no charge.
FAQ
Does a full-page screenshot include content below the fold?
Yes. Full-page mode captures the document’s full scrollable area, subject to content that has actually rendered.
Is a PDF the same as an image?
No. A PDF is a paginated document. Use an image format when you need one bitmap for previews, visual diffs, or an <img> tag.
Why is my capture different from what I see?
Viewport width, device scale, login state, geolocation, time, animations, ads, and late-loading resources can all change the rendered page. Fix those inputs before comparing images.
Can I capture just one component?
Yes. Playwright can screenshot a locator, and ScreenshotNeo accepts a CSS selector for element capture.


