ScreenshotNeo

BlogHow-to

Use Playwright in Java to Screenshot a Page in Dark Mode

Emulate prefers-color-scheme: dark in Playwright for Java, then save a viewport, full-page, or element screenshot.

By the ScreenshotNeo team4 October 20267 min read

Set the browser context’s color scheme to ColorScheme.DARK before navigating, then call page.screenshot(). This tells the page that prefers-color-scheme: dark is active; the site must support that preference for its design to appear dark. The example below saves a full-page PNG.

import com.microsoft.playwright.*;
import java.nio.file.Paths;

public class DarkScreenshot {
  public static void main(String[] args) {
    try (Playwright playwright = Playwright.create()) {
      Browser browser = playwright.chromium().launch();
      BrowserContext context = browser.newContext(
          new Browser.NewContextOptions().setColorScheme(ColorScheme.DARK));
      try {
        Page page = context.newPage();
        page.navigate("https://example.com");
        page.screenshot(new Page.ScreenshotOptions()
            .setPath(Paths.get("dark-page.png"))
            .setFullPage(true));
      } finally {
        context.close();
        browser.close();
      }
    }
  }
}

Playwright’s Java emulation guide documents context-level and page-level color-scheme configuration. See the screenshot guide for capture options and the ScreenshotNeo API documentation for the hosted alternative below.

1. Set up Playwright for Java

Use the Playwright Java dependency in a Maven project. The official installation guide has the current dependency version, system requirements, and complete setup details. Keep the library version and installed browser binaries aligned.

<dependency>
  <groupId>com.microsoft.playwright</groupId>
  <artifactId>playwright</artifactId>
  <version>YOUR_PLAYWRIGHT_VERSION</version>
</dependency>

Install the browser binaries for the engine you plan to use. For example, with the project’s Playwright CLI configured:

mvn exec:java -D exec.mainClass=com.microsoft.playwright.CLI -D exec.args="install chromium"

Playwright browsers run headless by default, so a desktop UI is not required for this script. Use a supported Java runtime and check the current installation guide for platform requirements, which can change.

2. Configure dark mode before navigation

Context configuration is the clearest option when every page in an isolated browser session should see the same color preference:

BrowserContext context = browser.newContext(
    new Browser.NewContextOptions().setColorScheme(ColorScheme.DARK));
Page page = context.newPage();
page.navigate("https://example.com");

You can also create a convenience page directly with the preference:

Page page = browser.newPage(
    new Browser.NewPageOptions().setColorScheme(ColorScheme.DARK));

For an already-created page, emulate the media feature before capture:

page.emulateMedia(new Page.EmulateMediaOptions()
    .setColorScheme(ColorScheme.DARK));

If possible, set the preference before navigation so page scripts that inspect it during initialization see the intended value. This is a practical ordering choice; pages differ in how and when they read the preference.

3. Capture the viewport, full page, or an element

Viewport screenshot

Omit setFullPage(true) to capture the currently visible viewport:

page.screenshot(new Page.ScreenshotOptions()
    .setPath(Paths.get("dark-viewport.png")));

Full-page screenshot

Set fullPage to include the full scrollable page:

page.screenshot(new Page.ScreenshotOptions()
    .setPath(Paths.get("dark-full-page.png"))
    .setFullPage(true));

Very long pages can produce large images and may trigger lazy-loaded content only as the page is rendered or scrolled. If completeness matters, verify that the site has loaded its below-the-fold content before relying on the image.

Screenshot one element

Use a locator for a matched element. Locator screenshots scroll the element into view and perform actionability checks:

page.locator("main article").screenshot(
    new Locator.ScreenshotOptions()
        .setPath(Paths.get("dark-article.png")));

Prefer locator screenshot methods over the discouraged ElementHandle screenshot API. A selector that matches nothing, matches multiple unexpected elements, or identifies a hidden element can prevent the capture or select the wrong content.

4. Choose format and output scale

The screenshot API supports image format, clipping, quality, and other capture options; check the API documentation for the Playwright version installed in your project. Common choices include:

  • PNG: lossless output and the usual default when the path ends in .png.
  • JPEG: lossy and often smaller for photographic content; quality is relevant to JPEG.
  • WebP: supported by current screenshot APIs; verify format support for your installed version and consumers.
  • CSS scale: roughly one output pixel per CSS pixel.
  • Device scale: uses device pixels and can create a larger, higher-resolution output.

Choose the filename extension and explicit format consistently. If you need the image in memory instead of on disk, call page.screenshot() to get a byte[] buffer and write or process those bytes yourself.

5. Check whether the page received the dark preference

Use matchMedia to verify the browser preference from page JavaScript:

Object darkPreference = page.evaluate(
    "() => matchMedia('(prefers-color-scheme: dark)').matches");
System.out.println("Dark preference: " + darkPreference);

A true result confirms that the media feature is emulated. It does not prove the site has dark styles, that a separate application-level theme toggle is enabled, or that every component uses the preference. Some sites persist a user choice that overrides the system setting.

6. Troubleshooting

Symptom Likely cause What to do
The screenshot still looks light The site does not implement dark styles for prefers-color-scheme, or a saved theme choice overrides it. Check matchMedia('(prefers-color-scheme: dark)').matches. If it is true, inspect the site’s theme behavior; Playwright emulates the preference but does not force a site’s own toggle.
The first render uses the wrong theme The preference was changed after navigation, or the application read it only during startup. Set ColorScheme.DARK on the context before creating the page and navigating.
Browser launch reports missing executables The browser binary for this Playwright version has not been installed, or the library was upgraded without updating browser binaries. Run the Playwright CLI browser installation for the engine you launch. Consult the browser installation guide.
Navigation times out The target is slow, unreachable, or waiting for a load state the page does not reach promptly. Check network access and the URL. Choose an appropriate navigation wait condition or timeout for the site; do not treat a timeout as proof that a screenshot is complete.
Output file is missing or unexpectedly named The path points to a different working directory, or its extension does not match the intended format. Use an absolute or known output path, create its parent directory, and set the screenshot format consistently with the extension.
Full-page capture is huge or incomplete The page is exceptionally long, content is lazy-loaded, or the image consumer has size limits. Wait for required content, consider viewport or element capture, and check memory and downstream image-size limits.
Element capture fails The locator is absent, ambiguous, hidden, or not ready. Use a stable selector, wait for the element to become visible, and confirm it matches the intended element.
Browser process or resources remain after capture Context or browser cleanup did not run after an exception. Use try-with-resources for Playwright and a finally block to close the context and browser, as in the complete example.

7. Performance, reliability, and cost

Each local capture starts or uses a browser process, loads the target page, and encodes an image. For repeated work, reuse a browser process where appropriate while creating isolated contexts for separate sessions; close contexts and browsers when finished. Full-page and device-scale captures can use more memory and produce larger files than viewport captures.

Capture reliability depends on the target site, network, browser version, and how the page signals readiness. Choose a wait condition based on the content you need, and handle navigation and screenshot errors explicitly. Keep Playwright and its browser binaries in sync, especially in CI, and avoid assuming that one successful capture means a dynamic page is complete.

Playwright is software you run in your own environment; practical cost includes the compute, storage, and maintenance you provide for browser execution. ScreenshotNeo offers a hosted screenshot API if you want to skip browser installation and management. Its billing rules and plan prices are described in the product section below.

8. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. One GET request returns a PNG, JPEG, WebP, or PDF. Here is a cURL example using a placeholder key:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

See the ScreenshotNeo API documentation for request options. The API supports dark mode and other capture controls. Cookie banners, newsletter popups, and chat widgets are removed before the shot; each step can be turned off. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for Claude, Cursor, and other MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.

Sign up free for 1,000 screenshots a month, with no card required.

9. FAQ

Does Playwright’s dark setting change the operating system theme?

No. It emulates the browser media preference for the page; it does not change the host operating system’s appearance.

Can I emulate light mode too?

Yes. Use ColorScheme.LIGHT in the context or page options, or set it with Page.emulateMedia.

Does dark mode affect PDFs?

The color scheme and PDF printing are separate concerns. A page may respond to dark preference while print styles choose a different appearance. Verify the document output for the site and settings you use.

Can I capture without saving a local file?

Yes. The screenshot method returns image bytes when no path is supplied; store, process, or transmit the returned buffer in your application.