Capture a Full-Page Website Screenshot in Java with Playwright
Use Playwright Java’s `setFullPage(true)` to capture a page beyond the viewport. Save the image to disk, tune capture options, and handle common edge cases.
Use Playwright Java’s page screenshot method and set fullPage to true. This captures the full scrollable document rather than only the visible viewport:
page.screenshot(new Page.ScreenshotOptions()
.setPath(Paths.get("full-page.png"))
.setFullPage(true));
The complete runnable example below launches Chromium, opens a URL, and saves a PNG. Chromium is one browser choice; this API pattern is not limited to Chromium. See the Playwright Java screenshots guide and Page API reference.
1. Create and save a full-page screenshot
import com.microsoft.playwright.*;
import java.nio.file.Paths;
public class FullPageScreenshot {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
Browser browser = playwright.chromium().launch();
try {
Page page = browser.newPage();
page.navigate("https://example.com");
page.screenshot(new Page.ScreenshotOptions()
.setPath(Paths.get("full-page.png"))
.setFullPage(true));
} finally {
browser.close();
}
}
}
}
Install Playwright Java and its browser binaries by following the official Java introduction. Run the class with Playwright on the project classpath and ensure the browser installation step has been completed for the environment.
- Create a Playwright instance and launch a browser.
- Create a page and navigate to the target URL.
- Call
page.screenshotwithsetFullPage(true). - Set a path if you want a file; otherwise handle the returned bytes.
The example closes the browser even if capture throws. The Playwright try-with-resources block also closes the Playwright instance.
2. Save the bytes or choose an output format
setPath(Paths.get("full-page.png")) writes the image to that path. Relative paths resolve from the Java process’s current working directory. When a path is provided, the file extension determines the screenshot type. Without a path, screenshot returns a byte[] and does not save to disk:
byte[] image = page.screenshot(new Page.ScreenshotOptions()
.setFullPage(true));
Files.write(Paths.get("full-page.png"), image);
Add import java.nio.file.Files; for this variant. You can instead pass the bytes to another library or encode them for transport. Playwright’s guide also shows converting screenshot bytes to Base64.
The API supports PNG, JPEG, and WebP. Choose the format with the filename extension or the screenshot type option supported by your installed Playwright version. JPEG and WebP support a quality value from 0 to 100; PNG does not use that setting. PNG is a convenient lossless default, while JPEG or WebP may suit workflows where smaller output matters. Confirm format support in the version-specific API reference.
3. Relevant screenshot options
| Option | Behavior and when to use it |
|---|---|
setFullPage(true) |
Captures the full scrollable page. The default is false, which captures the viewport. |
setPath(Path) |
Saves the output to a path. If omitted, the call returns image bytes without writing a file. |
setType(...) or file extension |
Selects PNG, JPEG, or WebP, subject to the installed version’s supported options. |
setScale(ScreenshotScale.CSS) |
Produces one image pixel per CSS pixel. |
setScale(ScreenshotScale.DEVICE) |
Uses device pixels. This is the documented default and can create larger images on high-DPI displays. |
setQuality(int) |
Sets JPEG or WebP quality from 0 through 100; it does not affect PNG. |
setTimeout(double) |
Sets the screenshot operation timeout. The documented default is 30 seconds; 0 disables the timeout. |
setStyle(String) |
Injects stylesheet text during capture. It can hide dynamic elements or make output more repeatable; the documented injected style applies through Shadow DOM and inner frames. |
setMask(...) |
Masks selected locators in the screenshot, useful when specific regions should be obscured. |
Check the Page API reference for exact Java types and overloads for your Playwright version. Use setStyle for temporary visual adjustments at capture time; it does not change the site itself.
4. Page screenshots versus element screenshots
Use Page.screenshot with setFullPage(true) when you need the whole document. Use Locator.screenshot when you need a matched element, such as a chart or card. A screenshot of a scrollable element includes only its currently scrolled content; it does not automatically turn that element’s internal scroll area into a full-page capture. See the Locator API reference.
Full-page capture means the document’s scrollable extent. It does not guarantee that every piece of content on a site will appear: content that loads only after interaction, authentication, or a particular scroll event may need additional setup. A fixed-position element can also appear differently in a tall capture than it does during ordinary scrolling.
5. Make the page ready before capture
Navigation completing does not necessarily mean every visual element is ready. If the page has delayed content, wait for an appropriate selector or for the site-specific condition that indicates the content is ready. For lazy-loaded sections that appear only as the user scrolls, a full-page screenshot request alone may not trigger the site’s own loading behavior. Determine how the target site loads its content and prepare it before capturing.
For repeatable output, use a consistent viewport, browser, device scale, and page state. You can inject a style with setStyle to hide animations or other changing elements. The API documents that the style applies through Shadow DOM and inner frames. Avoid assuming a single wait condition works for every application.
6. cURL, Python, and Node.js alternatives
These examples call Playwright’s official CLI or Node.js API, not the Java API. They are useful when the capture runs in a shell script or a project already uses those runtimes. Install Playwright and its browser binaries as described in the Playwright installation guide.
cURL through the Playwright CLI
After installing the Playwright CLI and browser, the CLI can take the screenshot; cURL itself does not control a browser. For a Java project, prefer the Java API shown above.
npx playwright screenshot --full-page https://example.com full-page.png
Python
from pathlib import Path
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.launch()
try:
page = browser.new_page()
page.goto("https://example.com")
image = page.screenshot(full_page=True)
Path("full-page.png").write_bytes(image)
finally:
browser.close()
Node.js
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com');
await page.screenshot({ path: 'full-page.png', fullPage: true });
} finally {
await browser.close();
}
})();
7. Or skip the browser setup
If you need a screenshot without managing browser installation and page capture code, ScreenshotNeo is a website screenshot API and MCP server for developers, made by Yorker Media. It accepts one GET request with a URL and returns a PNG, JPEG, WebP, or PDF. Its options include full-page capture with lazy images loaded. The API documentation has the request details.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
const image = Buffer.from(await res.arrayBuffer());
require('node:fs').writeFileSync('shot.webp', image);
ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot. Bot checks, blank pages, and failed loads are never billed. Its MCP server lets AI agents take screenshots. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000. Sign up for 1,000 free screenshots a month with no card.
8. Troubleshooting
| Symptom | Likely cause | What to try |
|---|---|---|
| Only the viewport appears | setFullPage(true) was omitted, or the code called a different screenshot overload. |
Set setFullPage(true) on Page.ScreenshotOptions and call page.screenshot. |
| No image file appears | No path was supplied, or the relative path points to a different working directory. | Set setPath(Paths.get("full-page.png")) or write the returned bytes yourself; check the process working directory. |
| Screenshot times out | The capture exceeded the screenshot timeout, which defaults to 30 seconds. | Wait for the page to reach the required state before capture, then raise setTimeout if needed. Setting it to 0 disables the screenshot timeout, but does not make a slow page faster. |
| Images or sections are missing | Content may be lazy-loaded or dependent on scrolling, interaction, or authentication. | Prepare the page according to the site’s loading behavior before taking the screenshot. Full-page mode captures the scrollable document but does not establish that every deferred state has loaded. |
| Output is unexpectedly large | A tall page, device-pixel scaling, or a lossless format can increase image dimensions or file size. | Consider CSS scale, JPEG or WebP with an appropriate quality, or capturing only a needed element. |
| Quality setting has no effect | Quality applies to JPEG and WebP, not PNG. | Choose JPEG or WebP if lossy quality control is needed. |
| Capture differs between runs | Dynamic content, animation, viewport, or device scale may vary. | Use a consistent viewport and scale; wait for the relevant state and inject capture-time CSS to hide changing elements where appropriate. |
9. Performance, reliability, and cost
A full-page image can be much taller and larger than a viewport screenshot. Device-pixel scale can increase the pixel count further. Large captures take more memory and time to encode and write, so use CSS scale or a compressed format when the downstream workflow allows it. For a single chart or component, an element screenshot avoids capturing unrelated page area.
Playwright runs a browser process, so account for browser startup and page loading in the runtime of a batch job. Reuse a browser for multiple pages when building a worker, while keeping each page’s navigation and state isolated as your workflow requires. Set a finite timeout appropriate to the job and handle navigation and screenshot failures explicitly. Cost depends on where and how you run the browser; the documentation cited here does not specify a hosted capture price.
10. FAQ
Does full-page mode scroll the page and stitch screenshots?
The documented behavior is a screenshot of the full scrollable page as if it fit on a very tall screen. The API describes the resulting capture behavior rather than requiring application code to scroll and stitch images.
Can I get bytes without creating a file?
Yes. Omit the path and use the returned byte[]. Write it to disk or pass it to another component as needed.
Can I capture just one element?
Yes. Use a locator screenshot for a matched element. For scrollable elements, expect only the currently scrolled content of that element.
Can I use the same Java API with every browser engine?
The documented screenshot API is page-level, while the sample uses Chromium as an illustrative launch choice. Consult Playwright’s Java documentation for browser installation and engine-specific details.


