ScreenshotNeo

BlogHow-to

Take a Screenshot of a Website in Node.js with Playwright and Save It as JPEG

Use Playwright’s page.screenshot() to save a website capture as JPEG. Learn setup, quality and full-page options, and how to fix common failures.

By the ScreenshotNeo team4 October 20265 min read

Use Playwright’s page.screenshot() method after navigating to the website. Set a .jpeg output path and, for clarity, pass type: 'jpeg'. The example below saves a viewport screenshot at JPEG quality 80.

const { chromium } = require('playwright');

(async () => {
  const browser = await chromium.launch();
  try {
    const page = await browser.newPage();
    await page.goto('https://example.com');
    await page.screenshot({
      path: 'screenshot.jpeg',
      type: 'jpeg',
      quality: 80,
    });
  } finally {
    await browser.close();
  }
})();

Playwright infers the format from the filename extension when saving to a path, so the explicit type is optional if the path ends in .jpeg. See the official Playwright Page API.

1. Install Playwright

Start a Node.js project and install Playwright. The package downloads browser binaries with the install command; if you install browsers separately or use a fresh environment, run the browser install step too.

npm init -y
npm install playwright
npx playwright install chromium

Save the example as screenshot.js, then run:

node screenshot.js

The file screenshot.jpeg is written relative to the process current working directory, which is the directory from which you run node.

2. Configure the screenshot

JPEG format and quality

The supported screenshot types are png, jpeg, and webp. With a file path, Playwright infers the type from its extension. Setting type: 'jpeg' makes the intended format explicit. JPEG quality ranges from 0 to 100 and defaults to 80. Higher values generally preserve more image detail and produce larger files; choose a value appropriate for your storage and visual requirements.

Option Effect JPEG guidance
path Writes the screenshot to disk. If omitted, the method returns an image buffer. Use a .jpg or .jpeg path for inferred JPEG output.
type Chooses png, jpeg, or webp. Set jpeg if you want the format explicit.
quality Controls lossy image quality from 0 to 100; documented default is 80. Applies to JPEG, not PNG.
fullPage Captures the full scrollable page instead of the viewport. Set true when the entire page is needed; default is false.

Viewport versus full page

By default, Playwright captures the visible viewport. Set fullPage: true to capture the full scrollable document:

await page.screenshot({
  path: 'full-page.jpeg',
  type: 'jpeg',
  quality: 80,
  fullPage: true,
});

Full-page images can be much taller and larger than viewport captures. If your goal is a single screen for a report or preview, keep the default. If you need the complete page, use full-page capture and account for its larger output.

Return a buffer instead of writing a file

Omit path to get image bytes back. You can then pass the buffer to storage or another library:

const image = await page.screenshot({ type: 'jpeg', quality: 80 });
console.log(`Captured ${image.length} bytes`);

omitBackground does not make JPEG transparent. JPEG does not support transparency; use a format with transparency, such as PNG, if a transparent background is required.

3. Make captures more reliable

Navigation and screenshot capture are separate steps. If the target page needs more time to render, wait for a page-specific condition before taking the screenshot. For example, wait for a key element that indicates the content you need is present:

await page.goto('https://example.com');
await page.locator('main').waitFor({ state: 'visible' });
await page.screenshot({ path: 'ready.jpeg', type: 'jpeg', quality: 80 });

Replace main with a selector that exists on your target site. A fixed delay can help with a known delay, but waiting for a meaningful element is usually more reliable than guessing how long the page needs.

For a consistent viewport, configure it when creating the page:

const page = await browser.newPage({
  viewport: { width: 1365, height: 768 },
});

Keep the browser cleanup in a finally block so the process closes Chromium if navigation or capture throws an error. For batches, reuse a browser process and create a page per capture rather than launching a new browser for every URL; close each page when finished and close the browser when the batch ends.

4. Common problems and fixes

Problem Likely cause Fix
Playwright cannot find Chromium The browser binary was not installed in this environment. Run npx playwright install chromium for the installed Playwright version.
The screenshot is PNG instead of JPEG The path extension or explicit type requests PNG. Use a .jpeg path and set type: 'jpeg'.
The capture shows a loading state or missing content The screenshot was taken before the target content appeared. Wait for a visible content selector before capturing.
The output file is missing The path is relative to a different current working directory than expected, or the process failed before capture. Check the directory from which you ran Node, use an absolute path if needed, and inspect thrown errors.
The image is unexpectedly large A high quality setting or full-page capture increased the output size. Lower JPEG quality, capture only the viewport, or resize the image in a separate image-processing step.
Transparency is absent JPEG cannot store transparent pixels. Choose PNG when transparency matters; omitBackground does not add transparency to JPEG.

5. Performance, reliability, and cost

A local Playwright capture uses your machine or server resources: Node.js, a browser process, memory for the page and image, and storage for output files. The practical cost depends on where it runs and how many captures you make. Reusing a browser for a batch avoids repeated browser startup; full-page captures and high quality output can increase processing, memory, and file-size needs.

For reliable automation, handle navigation and screenshot errors, close pages and browsers in cleanup paths, and avoid assuming every site renders at the same speed. For sites behind bot checks or pages with consent banners, popups, or chat widgets, a raw browser capture may include those elements or fail to reach the intended content.

Or skip the browser setup

ScreenshotNeo takes website screenshots through one API request and can return PNG, JPEG, WebP, or PDF. Its API accepts the URL and an access key; see the ScreenshotNeo API documentation for request options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

These examples use the API’s default output. Configure the format and other capture options in the API request as described in the docs. ScreenshotNeo removes cookie banners, popups, and chat widgets before the shot; bot checks, blank pages, and failed loads are never billed; an MCP server lets AI agents take screenshots; and 1,000 screenshots a month are free with no card, with paid plans starting at $5 for 3,000.

Sign up for ScreenshotNeo and get 1,000 free screenshots a month with no card.

FAQ

Does the filename have to end in .jpeg?

No. You can set type: 'jpeg' explicitly. When saving to a path, using a matching extension makes the output intent clear and lets Playwright infer the format.

Can I use a JPEG quality above 80?

Yes. The documented range is 0 to 100; 80 is the default. Higher values are available when you need them.

Does fullPage: true change the viewport?

No. It captures the full scrollable page rather than just the visible viewport.

Which browsers can Playwright launch?

Playwright’s Page API examples use Chromium, Firefox, and WebKit. The code here uses Chromium; install the browser binaries needed by your environment.