ScreenshotNeo

BlogHow-to

How to Capture a Page Screenshot with a Transparent Background in Puppeteer

Use Puppeteer’s `omitBackground: true` option to capture transparent PNG screenshots. See full-page and element examples, fixes for opaque results, and an API alternative.

By the ScreenshotNeo team4 October 20266 min read

Set omitBackground: true in Puppeteer’s screenshot options and save the result as a PNG. This hides the browser’s default white background. If the page itself paints a background with CSS, that authored background may still appear in the image.

const fs = require('node:fs/promises');
const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com', { waitUntil: 'networkidle0' });

    await page.screenshot({
      path: 'page.png',
      type: 'png',
      omitBackground: true,
    });
  } finally {
    await browser.close();
  }
})();

type: 'png' is optional when the output path ends in .png: PNG is Puppeteer’s default screenshot type, and the file extension can determine the format. See the ScreenshotOptions reference and the Puppeteer screenshots guide.

Capture the full page or one element

Choose the screenshot method based on the content you need. A normal page screenshot captures the viewport; fullPage: true captures the full document, while an element handle captures one selected element.

Full-page transparent PNG

await page.screenshot({
  path: 'full-page.png',
  fullPage: true,
  omitBackground: true,
});

Full-page capture can produce a very tall image. Large pages may use substantial memory and take longer to render and encode.

Transparent screenshot of one element

const element = await page.waitForSelector('.target', { timeout: 10_000 });
if (!element) {
  throw new Error('Could not find .target');
}

await element.screenshot({
  path: 'element.png',
  omitBackground: true,
});

ElementHandle.screenshot() scrolls the element into view if needed. It throws if the element has been detached from the DOM, so wait for the page to settle and avoid replacing the target between selection and capture. See the ElementHandle.screenshot() reference.

Control transparency when the page has its own background

omitBackground hides the browser’s default white backdrop; it does not guarantee that CSS backgrounds authored by the site disappear. If a PNG still looks opaque, inspect the document and the captured element for background colors or images.

When it is appropriate to remove the page’s own background for the capture, apply a temporary style before taking the screenshot:

await page.addStyleTag({
  content: `
    html, body {
      background: transparent !important;
    }
  `,
});

await page.screenshot({
  path: 'transparent.png',
  omitBackground: true,
});

This changes the rendered page for the capture. A background applied to a nested container or the target element may need a more specific selector. Removing a background can also make text or icons unreadable if they were designed to appear over it.

Options and output handling

Need Option or approach Details
Transparent image omitBackground: true Boolean option; defaults to false.
PNG file path: 'image.png' PNG is the default screenshot type. The path extension can be used to infer the type.
Full document fullPage: true Captures beyond the current viewport.
One element element.screenshot() Captures the element after scrolling it into view when needed.
In-memory bytes Omit path page.screenshot() returns a Uint8Array by default.
Base64 output Request the base64 encoding option Useful when an API needs a string instead of bytes; account for the extra encoded size.
JPEG quality quality JPEG quality does not apply to PNG output.

For example, save the returned bytes yourself instead of asking Puppeteer to write a path:

const bytes = await page.screenshot({ omitBackground: true });
await fs.writeFile('page.png', bytes);

The returned screenshot data is a Uint8Array by default; the API also supports base64 output through its encoding option. Refer to the Page.screenshot() API reference for the current option names and types.

Complete command-line example

This example accepts a URL and output path, waits for the page to load, and writes a transparent PNG. Install Puppeteer in a project first with npm install puppeteer, then save this as capture.js.

const puppeteer = require('puppeteer');

(async () => {
  const [url, outputPath = 'page.png'] = process.argv.slice(2);
  if (!url) {
    console.error('Usage: node capture.js <url> [output.png]');
    process.exitCode = 1;
    return;
  }

  const browser = await puppeteer.launch({ headless: true });
  try {
    const page = await browser.newPage();
    await page.goto(url, {
      waitUntil: 'networkidle0',
      timeout: 30_000,
    });
    await page.screenshot({
      path: outputPath,
      type: 'png',
      omitBackground: true,
      fullPage: true,
    });
    console.log(`Saved ${outputPath}`);
  } finally {
    await browser.close();
  }
})();

Run it with node capture.js https://example.com output.png. Some sites keep connections open, so networkidle0 may not occur before the timeout. In that case, use a different navigation wait condition and explicitly wait for the content you need.

Troubleshooting

Symptom Likely cause Fix
PNG background is still white or colored The page or target paints its own CSS background. Inspect computed styles and background images on html, body, and the target. If suitable, override those styles before capture as shown above.
PNG appears to have no transparency in an image viewer The viewer may display transparent pixels against a white canvas, making them hard to distinguish. Check the image over a colored background or inspect its alpha channel with an image tool.
Target selector times out The selector is wrong, content has not loaded, or the target is inside a frame. Verify the selector in the correct frame and wait for the page’s actual content-ready condition.
Element screenshot reports a detached node The framework replaced or re-rendered the element after it was selected. Wait for the final UI state, then query the element again immediately before capture.
Navigation times out waiting for network idle Analytics, streaming, or long-lived requests prevent the page from becoming idle. Use an appropriate navigation condition such as domcontentloaded, then wait for a selector or other specific readiness signal.
Transparency is lost after processing A later conversion or image format does not preserve alpha. Keep the output as PNG through the full pipeline and verify the downstream encoder preserves transparency.

Performance, reliability, and cost

  • Capture only what you need. A viewport or element screenshot generally contains fewer pixels than a very tall full-page image, which can reduce processing and storage costs in your own workflow.
  • Wait for the right condition. Network-idle waits can be unreliable on pages with persistent requests. Prefer a specific selector or application-ready signal when available.
  • Close the browser in a finally block. This releases browser resources even when navigation or capture fails.
  • Handle retries selectively. Retry transient navigation failures with a limit and backoff; do not retry permanent selector errors without correcting the page or selector.
  • Keep PNG for alpha. Choose output handling that preserves transparency when passing the file to another service or converting it.

Puppeteer is a browser automation library; this method has no per-screenshot API fee from Puppeteer itself. Your compute, browser hosting, storage, and image-processing costs depend on where and how you run the capture.

Or skip the browser setup

ScreenshotNeo provides a screenshot API: one GET request returns an image or PDF. For a transparent background, use its documented API options for the capture.

curl -G "https://api.screenshotneo.com/v1/shot" \
  -d access_key=YOUR_API_KEY \
  --data-urlencode url=https://stripe.com \
  -d transparent=true \
  -o shot.png

Cookie banners, newsletter popups, and chat widgets are removed before the shot. Bot checks, blank pages, failed loads, timeouts, and cache hits are never billed; response headers report the page verdict and billing status. An MCP server lets AI agents use take_screenshot, get_page_info, and capture_pdf. The free plan includes 1,000 screenshots a 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.

FAQ

Does omitBackground make the whole webpage transparent?

It removes the browser’s default white background. CSS backgrounds painted by the page can remain, so inspect and adjust the relevant styles when needed.

Do I need to set type: 'png'?

No, PNG is Puppeteer’s documented default, and a .png path can determine the image type. Setting it explicitly can make the intent clearer.

Can I capture only an element with transparency?

Yes. Wait for an ElementHandle and call its screenshot() method with omitBackground: true.

Can I use JPEG for a transparent screenshot?

Use PNG for the requested transparency. JPEG quality settings do not apply to PNG, and JPEG is not an alpha-preserving output format.