The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Use Puppeteer’s page.emulateMediaFeatures() to set the page’s prefers-color-scheme preference to dark, then capture it with page.screenshot(). Set the preference before navigation if the page needs it during its initial render.
Set dark mode and take the screenshot
This runnable example uses Puppeteer’s documented media-feature setting and saves a PNG:
As an Amazon Associate I earn from qualifying purchases.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.emulateMediaFeatures([
{ name: 'prefers-color-scheme', value: 'dark' },
]);
await page.goto('https://example.com', { waitUntil: 'networkidle2' });
await page.screenshot({ path: 'screenshot.png' });
} finally {
await browser.close();
}
Replace https://example.com with the page you want to capture. Puppeteer’s API documents the prefers-color-scheme feature with the value dark; its screenshot guide documents navigating to a page and capturing it. Puppeteer media-feature API · Puppeteer screenshots guide
Why set it before navigation?
Setting the preference before page.goto() lets the page see it while loading. This matters when initial HTML, styles, or scripts choose a theme during the first render. If the page is already open, you can still emulate the preference, but the site may need a rerender or a separate theme action to change what is shown.
#1 Best Overall
Verify that the page sees the dark preference
To check the browser media preference from the page, evaluate the same media query used by CSS:
const isDarkPreference = await page.evaluate(
() => matchMedia('(prefers-color-scheme: dark)').matches,
);
console.log(isDarkPreference); // true when the emulated preference is active
Puppeteer’s API example uses this matchMedia check. A true result confirms the page sees the dark preference; it does not confirm that the site’s visible theme has changed. See the API example.
Choose the screenshot output
Pass options to page.screenshot() to control the captured area and artifact. The documented options include:
path: save the image to a file. The file extension can determine the image type.type: explicitly choose an image format.fullPage: true: capture the full page rather than only the viewport.clip: capture a specified rectangle.omitBackground: true: omit the default background to allow transparency.
For example, a full-page capture is await page.screenshot({ path: 'full-page.png', fullPage: true });. See the ScreenshotOptions reference and Page.screenshot API for option details.
Rank #3
Troubleshoot a screenshot that still looks light
The dark media query returns false
Check that you awaited emulateMediaFeatures() on the same page used for navigation and capture, and that the feature and value are spelled exactly prefers-color-scheme and dark. Then rerun the matchMedia check.
The query returns true, but the site looks light
The emulation sets the browser’s media-feature preference; it does not force every site’s theme. A site may use its own theme toggle, saved setting, or other application logic. Inspect the page’s theme controls and, if needed, activate its dark theme separately before capturing.
The screenshot is incomplete or captures the wrong area
Wait for the page’s relevant content to be ready according to that site’s behavior before capturing. Use fullPage: true when you need the entire document, or clip when you need a particular region. Those options change capture scope, not the page’s theme.
Free tools Windows power users keep installed
One-click scans. No signup required.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server. One GET request can return an image or PDF; its options include dark mode, full-page capture, and viewport controls. It removes cookie/consent banners, newsletter popups, and chat widgets before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and responses identify the page verdict and billing status. Its MCP server provides screenshot tools for AI agents and MCP clients.
For a direct API call, create an API key and replace YOUR_API_KEY below. The request uses Stripe as the target example; change the URL to the page you need.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
See the ScreenshotNeo API documentation for request options. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000. Sign up for the free plan.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

