Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To capture a website screenshot with JavaScript, run a browser automation library such as Playwright or Puppeteer, navigate to the page, wait for the content you need, then call the page’s screenshot method. Use a viewport capture for what is visible in the browser, or enable full-page capture for the scrollable page. If you would rather send a URL to a hosted service than manage a browser, an HTTP screenshot API is another option.

Capture a website with Playwright

Playwright takes a screenshot of a rendered browser page. The key method is page.screenshot(); it saves a file when you provide a path. The following complete Node.js example launches Chromium, opens a page, waits for navigation, and saves a viewport screenshot. Playwright’s documentation shows the screenshot method and its options in the Page API.

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

(async () => {
  const browser = await chromium.launch();
  try {
    const page = await browser.newPage({
      viewport: { width: 1440, height: 900 }
    });

    await page.goto('https://example.com', {
      waitUntil: 'networkidle',
      timeout: 30000
    });

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

Install Playwright in your Node project and install its browser runtime before running the script. A typical setup is npm install playwright, followed by npx playwright install chromium. The script uses networkidle as an example readiness condition, not a universal rule: pages with continuously active requests may never reach it. Choose a wait condition suited to the site, or wait for a particular element when that is a better indication that the content is ready.

The example writes a PNG to the current working directory. Ensure the process has permission to write there, and use a distinctive path if multiple captures might overwrite one another. For a service that handles untrusted or arbitrary URLs, also consider resource limits, timeouts, network access controls, and how you isolate browser processes.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Save a full-page image

By default, the capture is of the browser viewport. Set fullPage: true to capture the full scrollable page:

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

A full-page image may be much taller and larger than a viewport shot. Playwright notes that a browser page can crash if it needs to allocate too much memory for a screenshot. For long pages or high-resolution output, consider whether you need the entire page, or whether a viewport or selected element will serve the downstream purpose.

Capture an element or a clipped region

If you need a component rather than the whole visible page, locate the element and use its screenshot method:

const card = page.locator('.product-card').first();
await card.screenshot({ path: 'product-card.png' });

Use a selector that uniquely identifies the intended content, and wait for it to appear before capturing if the page renders it asynchronously:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option
await page.locator('.product-card').first().waitFor();
await page.locator('.product-card').first().screenshot({
  path: 'product-card.png'
});

For a fixed rectangular area, use the clipping option in the page screenshot API. Element screenshots are generally easier to maintain when the target is a meaningful page component; clipping is useful when the capture must use fixed coordinates and dimensions. Check the API documentation for the exact option shape and coordinate behavior.

Capture a screenshot with Puppeteer

Puppeteer offers a similar Page.screenshot() method. Its documented default is image bytes returned as a Uint8Array; you can also supply a path to write a file. This example shows a file capture:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();
    await page.setViewport({ width: 1440, height: 900 });
    await page.goto('https://example.com', {
      waitUntil: 'networkidle2',
      timeout: 30000
    });
    await page.screenshot({ path: 'screenshot.png' });
  } finally {
    await browser.close();
  }
})();

For in-memory processing, omit path and retain the returned bytes:

const imageBytes = await page.screenshot();

Puppeteer also documents a base64 output option, as well as options for image type, full-page capture, and quality. Option availability and valid combinations depend on the library’s screenshot options; use the current Puppeteer Page.screenshot() documentation and ScreenshotOptions reference for the version you install. Do not assume an option documented for one library has the same name or behavior in the other.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Choose what the screenshot should contain

Viewport or full page

A viewport screenshot records the visible browser area at the configured viewport dimensions. It is a good fit for visual checks that compare a page at a specific screen size. Full-page mode captures the scrollable page instead, but can produce a very large image and requires more memory. Set the viewport deliberately so tests and previews are reproducible.

One element or region

Use an element capture when the output is a particular card, chart, or other component. Use a clipping region when you need a defined rectangle rather than a DOM element. A selector that matches nothing, matches the wrong element, or is evaluated before the page is ready can lead to a failure or an unhelpful image, so make the target and readiness condition explicit.

Image type and destination

Choose the output format and whether to write a file or keep the image in memory based on what consumes the result. Playwright and Puppeteer expose library-specific screenshot options; an API provider can have different defaults and accepted settings. Confirm the supported formats and quality controls for the API in use rather than carrying option names across implementations.

Lazy-loaded content

Some pages load images or other content only as the visitor scrolls. A full-page screenshot does not guarantee that every lazy-loaded asset has been requested and rendered. If an image is missing, inspect how that page triggers loading and, where appropriate, scroll through the page before capturing or wait for the relevant asset or selector. Browserless documents a scrollPage option for its own API to trigger lazy-loaded content before a full-page capture; that behavior is provider-specific, not a standard JavaScript screenshot option.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • Brand: Wiley
  • Set of 2 Volumes
  • A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers

Run the browser yourself or call a hosted API?

With Playwright or Puppeteer, your application controls the browser automation directly. That suits teams that need browser interactions and are prepared to install and manage the browser runtime. You also need to decide where browser processes run, how they are isolated, and how the application handles output, failures, and resource consumption.

A hosted screenshot API accepts an HTTP request and returns an image, with the provider managing the rendering service. The exact endpoint, authentication, request fields, and options vary by provider. Browserless, for example, documents a token-authenticated POST to its /screenshot endpoint, with a URL and optional settings for full-page capture, viewport, image type, clipping, and selector capture. Its response is an image. See the Browserless Screenshot API documentation for that provider’s current request contract.

For ScreenshotNeo, the hosted option to try first is ScreenshotNeo: it removes known consent banners, newsletter popups, and chat widgets before capture, and only clean shots are billed. Its API uses a GET request with a URL; see the ScreenshotNeo API documentation for parameters and response behavior.

Or skip the browser setup

Send a URL to ScreenshotNeo’s API to get an image response. For example, this cURL command saves a WebP screenshot of example.com:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

The equivalent JavaScript request in Node.js is:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);

This shows the request; check the response before treating it as an image, and handle HTTP errors and file output according to your application. Keep the API key out of browser-side code and source control. The API can return PNG, JPEG, WebP, or PDF. 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 a month with no card; paid plans start at $5 for 3,000. Sign up for ScreenshotNeo’s free plan.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Make captures reliable and manageable

Use an intentional readiness condition

Navigation completing does not necessarily mean every useful part of a page has rendered. Pick a readiness condition based on what the screenshot must show: a navigation milestone, a known selector, a short delay for a specific animation, or network idleness when the page’s traffic pattern permits it. There is no single wait strategy that fits every site. A persistent analytics connection, for example, can make network-idle waiting a poor choice.

Control dimensions and memory

Define viewport width and height for comparisons or repeatable previews. A larger viewport, full-page capture, or high-resolution output increases the amount of image data produced; very tall captures may also strain browser memory. If the output is for a thumbnail or preview, avoid capturing more pixels than the consumer needs. If exact visual comparison matters, keep viewport and device scale settings consistent between runs.

Handle navigation and output failures

Set a navigation timeout that matches your application’s needs and catch errors so one slow or inaccessible target does not silently break a batch. Write captures to a controlled location or retain returned bytes for the next processing step. Close browser instances in a finally block, as in the examples, so errors do not leave browser processes running. For hosted APIs, follow the provider’s authentication and error-response guidance, and treat its response format as provider-specific.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Protect credentials and the browser environment

Do not embed hosted API keys in public client-side JavaScript; route requests through a backend or another secret-safe environment. A local browser that can navigate arbitrary URLs also has access to network destinations from its runtime, so applications that accept user-supplied URLs should assess access controls and isolation. These are deployment decisions rather than screenshot-method options.

Troubleshooting common screenshot problems

  • The file is blank or missing content: the page may not have finished rendering or may require an interaction. Wait for the specific content selector or the appropriate page state, then capture again.
  • Navigation times out: the target may be slow, unavailable, or continuously active. Check that the URL is reachable from the browser’s environment, use a suitable timeout, and choose a readiness condition that does not require all network activity to stop.
  • A lazy-loaded image is absent: the page may load it only after scrolling. Trigger the site’s loading behavior before capture or wait for the asset; for Browserless, consult its documented scrollPage setting.
  • The full-page capture is extremely large or the browser crashes: reduce the viewport or scale where appropriate, capture only the needed element or region, or split the page into smaller captures. Full-page screenshots can require substantial memory.
  • The wrong element is captured: verify the selector matches the intended element and wait for it to become available. If the selector is ambiguous, narrow it or select the intended match explicitly.
  • The output file is not where expected: a relative path is resolved from the process working directory. Use an explicit destination and confirm the process has write permission.
  • The hosted request returns an error instead of an image: verify the provider’s endpoint, authentication, URL encoding, and accepted options. Request shape and response behavior are not universal across hosted screenshot APIs.

Implementation checklist

  1. Choose local browser automation or a hosted endpoint based on where you want browser runtime management to happen.
  2. Navigate to the target and select a readiness condition appropriate to the site.
  3. Choose viewport, full page, element, or clipping capture deliberately.
  4. Set dimensions, image type, and output destination for the next step in your application.
  5. Account for lazy-loaded content and the memory cost of tall or high-resolution images.
  6. Protect credentials and verify current provider or library documentation for options and authentication.

Frequently Asked Questions

Are JavaScript website screenshots the same as screen recording?

No. These APIs capture a rendered browser page as an image; they do not record a video or capture the operating system’s screen.

Can I return screenshot bytes instead of writing a file?

Yes. Puppeteer’s documented default is screenshot bytes, and both browser libraries support output choices whose exact behavior depends on the API options.

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.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.