How to Capture a Website Screenshot with a Transparent Background Using Playwright
Capture transparent PNG screenshots with Playwright using omitBackground, with complete JavaScript and Python examples, fixes for common issues, and an API alternative.
To capture a website screenshot with a transparent background in Playwright, save it as PNG and set omitBackground: true in JavaScript or omit_background=True in Python. This hides the browser’s default white background. It does not remove backgrounds explicitly painted by the page’s CSS.
1. Capture a transparent screenshot in JavaScript
This runnable Node.js example opens a page and saves a viewport screenshot as a transparent PNG:
const { chromium } = require('playwright');
(async () => {
const browser = await chromium.launch({ headless: true });
try {
const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.screenshot({
path: 'screenshot.png',
type: 'png',
omitBackground: true
});
} finally {
await browser.close();
}
})();
Install Playwright and its browser first if needed: npm install playwright followed by npx playwright install chromium. The omitBackground option is documented by the Playwright Page API.
TypeScript
The same Page API works in TypeScript. For example, put this in capture.ts and run it with a TypeScript runner already configured in your project:
import { chromium } from 'playwright';
const browser = await chromium.launch({ headless: true });
try {
const page = await browser.newPage({ viewport: { width: 1280, height: 800 } });
await page.goto('https://example.com', { waitUntil: 'networkidle' });
await page.screenshot({ path: 'screenshot.png', type: 'png', omitBackground: true });
} finally {
await browser.close();
}
2. Capture in Python
In Playwright’s Python API, use the snake_case spelling omit_background. This asynchronous script saves the page screenshot as PNG:
import asyncio
from playwright.async_api import async_playwright
async def main():
async with async_playwright() as p:
browser = await p.chromium.launch(headless=True)
try:
page = await browser.new_page(viewport={"width": 1280, "height": 800})
await page.goto("https://example.com", wait_until="networkidle")
await page.screenshot(
path="screenshot.png",
type="png",
omit_background=True,
)
finally:
await browser.close()
asyncio.run(main())
Install the Python package and its browser with pip install playwright and playwright install chromium. The Python API uses omit_background, as shown in the Playwright Python API reference.
3. Choose the capture extent and output format
| Need | Setting | What to know |
|---|---|---|
| Visible viewport | Default screenshot behavior | Captures the current viewport. |
| Whole scrollable page | fullPage: true in JavaScript; full_page=True in Python |
Includes content beyond the viewport. It can take longer and create a much larger image. |
| Transparency | omitBackground: true / omit_background=True |
Use PNG. The option does not apply to JPEG. |
| JPEG output | type: 'jpeg' / type="jpeg" |
JPEG cannot preserve transparency. |
For a full-page transparent PNG in JavaScript, add fullPage: true:
await page.screenshot({
path: 'full-page.png',
type: 'png',
fullPage: true,
omitBackground: true
});
For Python, use:
await page.screenshot(
path="full-page.png",
type="png",
full_page=True,
omit_background=True,
)
Use full-page capture only when the artifact needs off-screen content. It does not change the page’s CSS, and a very long page may produce a large image.
4. Understand what becomes transparent
omitBackground hides Chromium’s default white background so transparent pixels can appear where the browser would otherwise paint that default. It does not erase a background color or image that the website explicitly draws with CSS. For example, if body has a white background set by the site, those pixels may remain white.
If you need a transparent page canvas, inspect the page’s styles and determine whether its background comes from the browser default or from site CSS. You can adjust styles for a controlled capture when appropriate, but doing so changes the rendered page and may affect its layout or appearance. Check the saved PNG over both a light and dark background to confirm the alpha channel and visible result meet your needs.
For a screenshot of a particular element, Playwright also provides locator screenshots. The same transparency setting can be applied to the screenshot options:
await page.locator('.product-card').screenshot({
path: 'product-card.png',
type: 'png',
omitBackground: true
});
The element’s own painted background remains part of the capture. If the selector does not match or the element is not visible, wait for it and check the selector before capturing.
5. cURL, Python, and Node.js using a screenshot API
Playwright runs a browser under your control. If you want an HTTP call instead of setting up a browser, ScreenshotNeo is a website screenshot API and MCP server. Its API supports transparent backgrounds; consult the ScreenshotNeo API documentation for request options and response details.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" \
-d access_key=YOUR_API_KEY \
--data-urlencode url=https://stripe.com \
-d format=png \
-d transparent=true \
-o shot.png
Python
import requests
r = requests.get(
"https://api.screenshotneo.com/v1/shot",
params={
"access_key": "YOUR_API_KEY",
"url": "https://stripe.com",
"format": "png",
"transparent": "true",
},
timeout=90,
)
r.raise_for_status()
open("shot.png", "wb").write(r.content)
Node.js
const q = new URLSearchParams({
access_key: 'YOUR_API_KEY',
url: 'https://stripe.com',
format: 'png',
transparent: 'true'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot request failed: ${res.status}`);
const fs = require('node:fs/promises');
await fs.writeFile('shot.png', Buffer.from(await res.arrayBuffer()));
These examples request PNG output and enable transparency. Check the current parameter names and response behavior in the linked docs when integrating, and keep your API key out of client-side code.
Or skip the browser setup
ScreenshotNeo can return a screenshot from one GET request. Cookie banners, popups, and chat widgets are removed before the shot. Bot checks, blank pages, and failed loads are never billed. An MCP server lets AI agents take screenshots. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Sign up for 1,000 free screenshots a month, with no card required.
6. Performance, reliability, and cost considerations
- Browser startup: Reuse a browser process for multiple captures in a controlled service, and create an isolated page or context per job as appropriate. Launching a fresh browser for every screenshot adds overhead.
- Wait strategy:
networkidlecan be useful for pages that settle, but analytics and long-polling can prevent a quiet network. If navigation hangs, use a suitable wait condition such asdomcontentloaded, then wait for a specific selector or a deliberate short delay. - Image size: Full-page captures can require more memory and produce larger PNGs than viewport captures. Use the smallest viewport and capture extent that satisfy the task.
- Repeatability: Keep browser version, operating system, viewport, settings, and headless mode consistent for visual baselines. Playwright documents these as factors that can change rendering in its visual comparisons guide.
- Cost: Self-hosted Playwright has no per-shot API charge, but it consumes your compute, storage, and engineering time. ScreenshotNeo’s listed plans range from 1,000 free monthly shots to paid tiers; only clean shots are billed, and responses identify page verdict and billing status in headers.
7. Troubleshooting
| Symptom | Likely cause | Fix |
|---|---|---|
| Image still has a white background | The website paints a white background in CSS, or the image viewer displays transparency as white. | Inspect the page’s background styles and inspect the PNG against a colored background. omitBackground only hides the browser’s default background. |
| Output has no transparency | The output was saved as JPEG or converted to a format/workflow that discarded alpha. | Save as PNG and avoid JPEG conversion. |
| Unknown option or option appears ignored in Python | Using JavaScript’s camelCase option name in Python. | Use omit_background=True in Python and omitBackground: true in JavaScript. |
| Navigation times out waiting for network idle | The page keeps network activity open, such as analytics or polling. | Use a less strict navigation wait and wait for the content needed in the screenshot. |
| Capture is incomplete or content is missing | The page has not rendered the required content, lazy content has not loaded, or the capture is viewport-only. | Wait for the relevant selector, scroll or trigger lazy content if needed, and use full-page capture when off-screen content belongs in the result. |
| Screenshot differs between runs or machines | Rendering environment, fonts, browser version, viewport, or headless mode differs. | Keep the capture environment and settings consistent; see Playwright’s visual comparison guidance. |
8. FAQ
Does transparent output work with JPEG?
No. JPEG does not preserve transparency. Save a PNG when transparent pixels matter.
Does omitBackground make every website background transparent?
No. It hides the browser’s default white background. Backgrounds the page explicitly paints can remain visible.
What is the Python spelling?
Use omit_background=True; JavaScript and TypeScript use omitBackground: true.
Can I capture only one element?
Yes. Use a locator’s screenshot method and pass the PNG and transparency options. The element’s own background styling still appears.


