How to Capture Dark Mode Screenshots of Any Website
Force dark mode rendering when capturing website screenshots. Works with CSS prefers-color-scheme, Tailwind dark mode, and custom implementations.
Last updated: 2026-03-25
Try ScreenshotAPI free
5 free credits. No credit card required.
Dark mode screenshots are essential for app store listings, documentation that matches user preferences, marketing sites, and design comparisons. Capturing dark mode programmatically requires emulating the browser's prefers-color-scheme: dark media query. This guide shows how to do it with both headless browsers and a screenshot API.
How Dark Mode Detection Works
Websites implement dark mode by responding to the CSS media query:
css@media (prefers-color-scheme: dark) { body { background-color: #1a1a1a; color: #ffffff; } }
When a browser reports that the user prefers dark mode, the site applies its dark styles. Screenshot tools can emulate this preference.
The Hard Way: Playwright
Playwright has native support for color scheme emulation.
javascriptimport { chromium } from 'playwright'; const browser = await chromium.launch(); const context = await browser.newContext({ viewport: { width: 1440, height: 900 }, colorScheme: 'dark' }); const page = await context.newPage(); await page.goto('https://github.com', { waitUntil: 'networkidle' }); await page.screenshot({ path: 'github_dark.png' }); await browser.close();
Capturing both modes
javascriptfor (const scheme of ['light', 'dark']) { const context = await browser.newContext({ viewport: { width: 1440, height: 900 }, colorScheme: scheme }); const page = await context.newPage(); await page.goto('https://github.com', { waitUntil: 'networkidle' }); await page.screenshot({ path: `github_${scheme}.png` }); await context.close(); }
Puppeteer (manual approach)
Puppeteer requires CDP commands to emulate color scheme:
javascriptimport puppeteer from 'puppeteer'; const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.emulateMediaFeatures([ { name: 'prefers-color-scheme', value: 'dark' } ]); await page.setViewport({ width: 1440, height: 900 }); await page.goto('https://github.com', { waitUntil: 'networkidle0' }); await page.screenshot({ path: 'github_dark.png' }); await browser.close();
Problems with browser-based dark mode capture
- Puppeteer's media emulation API is verbose
- Sites using JavaScript-based toggles (localStorage) may not respond to media queries
- Tailwind's
classdark mode strategy requires injecting a CSS class, not a media query - Managing browser processes for two screenshots per URL doubles resource usage
The Easy Way: ScreenshotAPI
ScreenshotAPI supports dark mode capture with a single colorScheme parameter.
Dark mode screenshot
bashcurl -G "https://screenshotapi.to/api/v1/screenshot" \ -d "url=https://github.com" \ -d "width=1440" \ -d "height=900" \ -d "colorScheme=dark" \ -d "type=png" \ -H "x-api-key: sk_live_your_api_key" \ --output github_dark.png
Light mode screenshot
bashcurl -G "https://screenshotapi.to/api/v1/screenshot" \ -d "url=https://github.com" \ -d "width=1440" \ -d "height=900" \ -d "colorScheme=light" \ -d "type=png" \ -H "x-api-key: sk_live_your_api_key" \ --output github_light.png
Both modes in JavaScript
javascriptconst API_KEY = process.env.SCREENSHOT_API_KEY; async function captureColorSchemes(url) { const results = {}; for (const scheme of ['light', 'dark']) { const params = new URLSearchParams({ url, width: '1440', height: '900', colorScheme: scheme, type: 'png', waitUntil: 'networkidle' }); const response = await fetch( `https://screenshotapi.to/api/v1/screenshot?${params}`, { headers: { 'x-api-key': API_KEY } } ); results[scheme] = Buffer.from(await response.arrayBuffer()); } return results; } const { light, dark } = await captureColorSchemes('https://github.com'); await fs.promises.writeFile('light.png', light); await fs.promises.writeFile('dark.png', dark);
Python
pythonimport requests API_KEY = "sk_live_your_api_key" for scheme in ["light", "dark"]: response = requests.get( "https://screenshotapi.to/api/v1/screenshot", params={ "url": "https://github.com", "width": 1440, "height": 900, "colorScheme": scheme, "type": "png", }, headers={"x-api-key": API_KEY}, ) with open(f"github_{scheme}.png", "wb") as f: f.write(response.content)
Use Cases for Dark Mode Screenshots
App store listings
App stores expect screenshots showing both light and dark appearances. Batch capture your web app in both modes:
javascriptconst pages = ['/dashboard', '/settings', '/analytics']; for (const path of pages) { for (const scheme of ['light', 'dark']) { const params = new URLSearchParams({ url: `https://yourapp.com${path}`, width: '1440', height: '900', colorScheme: scheme, type: 'png' }); const response = await fetch( `https://screenshotapi.to/api/v1/screenshot?${params}`, { headers: { 'x-api-key': process.env.SCREENSHOT_API_KEY } } ); const name = path.slice(1) || 'home'; const buffer = Buffer.from(await response.arrayBuffer()); await fs.promises.writeFile(`${name}_${scheme}.png`, buffer); } }
Documentation
Embed screenshots that match the reader's theme preference. Generate both versions and use CSS to swap them:
html<picture> <source srcset="/screenshots/dark.png" media="(prefers-color-scheme: dark)" /> <img src="/screenshots/light.png" alt="Dashboard screenshot" /> </picture>
Marketing materials
Dark mode screenshots on dark backgrounds create a sleek, modern look for landing pages and promotional materials.
Sites That Support Dark Mode
Most modern sites support prefers-color-scheme. Notable examples:
- GitHub, GitLab, Bitbucket
- Twitter/X, Reddit, Discord
- Stripe, Linear, Vercel
- MDN, Stack Overflow
- Most sites built with Tailwind CSS (media strategy)
Troubleshooting
Site renders in light mode despite colorScheme=dark: The site may use a JavaScript toggle (localStorage) instead of the CSS media query. Try adding a delay parameter to allow JavaScript to execute.
Colors look slightly different: Some sites blend media queries with custom theme logic. The screenshot reflects what a real user would see with dark mode enabled.
Next Steps
- Learn how to generate dark mode OG images for social sharing
- Capture full-page dark mode screenshots for complete page documentation
- Read the API documentation for all available parameters
- Check pricing for credit-based plans
Frequently asked questions
How does dark mode screenshot capture work?
The browser emulates the prefers-color-scheme: dark media query, which triggers CSS dark mode styles on the target page. This works with any site that uses the standard CSS media query for dark mode.
Does dark mode capture work with Tailwind CSS?
Yes, if the site uses Tailwind's media strategy (class='dark:bg-gray-900'). If the site uses Tailwind's class strategy with a manual toggle, the colorScheme parameter alone may not trigger it since it relies on a .dark class on the HTML element rather than the media query.
Can I capture both light and dark mode screenshots?
Yes. Make two API calls with colorScheme=light and colorScheme=dark respectively. This is useful for app store listings, documentation, and marketing materials.
What if the site does not support dark mode?
If the site has no dark mode CSS, the colorScheme parameter has no effect and the screenshot renders in the default light appearance.
Related resources
Start capturing screenshots today
Create a free account and get 5 credits to try the API. No credit card required. Pay only for what you use.