Halloween DealsAmazon USHalloween week deals: useful picks before month-endAmazon US: current deals, useful picks and tech finds.Check DealsClean PCRecommendedOne scan can reveal what keeps slowing WindowsLook for cleanup and repair opportunities.Run ScanHalloween DealsAmazon USOctober picks are moving - compare before checkoutAmazon US: current deals, useful picks and tech finds.See Picks×
Skip to content
World desk7 min

How to Take Website Screenshots with Puppeteer and Next.js

Create a Node.js Next.js Route Handler that captures a website with Puppeteer and returns image bytes, with practical guidance on readiness, browser installation, deployment, and failures.
Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

To take website screenshots with Puppeteer and Next.js, create an App Router Route Handler that runs in the Node.js runtime, opens the target URL in a compatible browser, captures the page, and returns the image bytes in an HTTP response. The key deployment requirement is that the server must be able to run a browser; a static export alone cannot handle screenshots generated on request.

Build a screenshot endpoint in the App Router

Install puppeteer in a Next.js project whose deployment can include its downloaded browser. Create app/api/screenshot/route.ts:

As an Amazon Associate I earn from qualifying purchases.

// app/api/screenshot/route.ts
import puppeteer from 'puppeteer';

export const runtime = 'nodejs';

export async function GET(request: Request) {
  const url = new URL(request.url).searchParams.get('url');
  if (!url) return new Response('Missing url', { status: 400 });

  const browser = await puppeteer.launch();
  try {
    const page = await browser.newPage();
    await page.goto(url, { waitUntil: 'networkidle2' });
    const image = await page.screenshot({ type: 'png', fullPage: true });
    return new Response(image, {
      headers: { 'Content-Type': 'image/png', 'Cache-Control': 'no-store' },
    });
  } finally {
    await browser.close();
  }
}

This example shows the route-level pattern; the precise import and browser launch configuration depend on the Puppeteer version and deployment environment. Next.js Route Handlers use Web Request and Response APIs and can return binary image data. GET handlers are not cached by default, but make the endpoint’s cache behavior deliberate. See the Next.js Route Handlers documentation.

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

Run the app in development, then request http://localhost:3000/api/screenshot?url=https%3A%2F%2Fexample.com. The response is a PNG; the route returns status 400 if the url parameter is missing.

Validate URLs before navigating

Do not expose unrestricted URL fetching to the public internet. A caller could try to make the server access internal network resources. Parse and validate the URL, allow only the schemes and destinations your application needs, and consider blocking private and link-local IP ranges after DNS resolution. Add authentication, rate limits, request timeouts, and resource limits appropriate to your application.

Handle failures and resource cleanup

The finally block closes the browser even when navigation or capture throws. In a production route, catch expected navigation and launch failures and return an intentional error response rather than an unhandled server error. Set a navigation timeout and decide how your application should report a target page that never becomes ready. For self-hosted Next.js, the official deployment guidance recommends a reverse proxy to help handle malformed requests, slow-connection attacks, payload limits, and rate limiting.

Choose when the page is ready

waitUntil: 'networkidle2' is one possible navigation condition, not a guarantee that a page has finished rendering visually. Some pages keep network requests open; others populate content, load fonts or lazy images, or run animations after network activity has settled. Puppeteer’s screenshot guide demonstrates navigation followed by capture, but readiness depends on the target site. See Puppeteer’s screenshot guide.

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

Use an application-specific readiness condition

For pages you control, expose a selector that appears only when the content needed for the screenshot is ready, then wait for it:

await page.goto(url, { waitUntil: 'domcontentloaded' });
await page.waitForSelector('[data-screenshot-ready="true"]', { timeout: 15000 });
const image = await page.screenshot({ type: 'png', fullPage: true });

For third-party pages, choose a reasonable navigation condition and, if necessary, wait for a known element or a short delay. No single wait strategy makes arbitrary websites visually stable; test it against the pages your endpoint is intended to capture.

Choose the capture scope and format

Capture How Useful for
Viewport page.screenshot() without fullPage A view of the current browser viewport, such as a preview or thumbnail.
Full page page.screenshot({ fullPage: true }) A capture of the page beyond the visible viewport.
One element Find an element and call its screenshot() method A specific component, card, chart, or other selected region.

Puppeteer supports screenshot options for output type, full-page capture, clipping a region, and transparent backgrounds. By default, screenshot data is returned as a Uint8Array; base64 output is available when requested. Refer to the ScreenshotOptions API and Page.screenshot() API for version-specific details.

Capture one DOM element

const element = await page.$('.pricing-card');
if (!element) {
  return new Response('Element not found', { status: 404 });
}
const image = await element.screenshot({ type: 'png' });

Puppeteer scrolls an element into view when needed before capturing it. Return the resulting bytes with Content-Type: image/png, just as for a page capture.

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

Use other screenshot options

  • Set type to a supported output format such as 'png', 'jpeg', or 'webp', and return the matching content type.
  • Use clip to capture a specific rectangle instead of the full page.
  • Use omitBackground: true when you need transparency, with an image format that supports it.
  • Set the viewport before navigation or capture when consistent dimensions matter. Puppeteer can also capture full-page output with fullPage: true.

Install and manage the browser

The puppeteer package normally downloads a compatible Chrome for Testing and chrome-headless-shell during installation. Puppeteer’s current installation guide gives approximate browser download sizes of 170 MB on macOS, 282 MB on Linux, and 280 MB on Windows. These are platform- and version-specific download figures, not the final size of an application or deployment image. Check the Puppeteer installation guide for current details.

Package choice Browser handling Trade-off
puppeteer Downloads a compatible browser during installation unless scripts or configuration prevent it. Simpler setup, but the deployed artifact must include the browser and fit the host’s constraints.
puppeteer-core Does not download Chrome; you provide a managed browser or connect to a remote one. More control over browser lifecycle and infrastructure, with more setup responsibility.

If your package manager blocks install scripts, the browser download may be skipped. Run Puppeteer’s documented browser installation command as part of the build or deployment process, or use a separately managed browser with puppeteer-core. Supply the browser path or connection configuration yourself when choosing that approach.

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

Deploy to a server-capable environment

A screenshot route needs both request-time server execution and a runnable browser. Next.js supports Node.js server and Docker deployments with all framework features; static export has limited feature support and cannot run this request-time browser task. Review the Next.js deployment documentation.

Hosting limits vary. Before choosing a platform, confirm its current support for browser executables and check artifact size, function duration, memory, and filesystem behavior. The general Next.js deployment guidance does not establish universal values for those provider-specific limits.

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

Decide whether to launch per request

The example launches and closes a browser for every request, which keeps the lifecycle easy to follow but repeats browser startup work. Reusing a browser process may reduce repeated startup, but introduces lifecycle, concurrency, and cleanup decisions that depend on the host. Choose based on the runtime model and its limits; do not assume a serverless instance will persist between requests.

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

Troubleshoot common failures

Symptom Likely cause What to check or change
Browser executable missing or launch fails The browser download was skipped, the browser is absent from the deployment artifact, or the configured path is wrong. Confirm installation scripts ran and the compatible browser is packaged. Use Puppeteer’s documented install command, or configure the managed/remote browser required by puppeteer-core.
Works locally but fails after deployment The host may not support the packaged browser or the function may exceed its artifact, memory, or duration limits. Check the selected provider’s current browser support and limits; consider a Node.js server or Docker deployment that can include the browser.
Navigation times out The target is slow, has ongoing requests, or never reaches the chosen readiness condition. Set a deliberate timeout, select an appropriate readiness condition, and use a target-specific selector when possible.
Screenshot is blank or missing content The page may not have rendered application data, fonts, or lazy-loaded media before capture. Wait for an application-ready selector or another target-specific signal, then verify the target page and capture options.
Response is not displayed as an image The returned content type does not match the screenshot format, or an error response was returned instead. Match Content-Type to the selected format and inspect the HTTP status and response body.
Element capture reports no element The selector is wrong or the element has not rendered yet. Check the selector and wait for it with page.waitForSelector() before calling element.screenshot().

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. Instead of installing and running a browser in your Next.js deployment, make one GET request:

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp

See the ScreenshotNeo API documentation for request options. ScreenshotNeo removes cookie banners, newsletter popups, and chat widgets before the shot; bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Its response identifies the page verdict and billing status in headers. An MCP server lets AI agents use its screenshot, page-info, and PDF tools. The Free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000 shots.

Sign up for ScreenshotNeo’s free plan to try 1,000 screenshots a month with no card.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

Performance, reliability, and cost considerations

  • Browser and artifact size: Include the compatible browser in deployment planning; the documented browser download alone is substantial and is not the complete artifact size.
  • Request duration: Navigation and page rendering can take longer than ordinary API work. Set timeouts and verify the chosen host’s current function-duration limits.
  • Concurrency: Each active browser consumes resources. Apply rate limits and concurrency controls that fit the deployment’s memory and workload.
  • Persistence: Returning screenshot bytes is sufficient when the caller needs an immediate image. Add storage only if captures need persistence or sharing beyond the response.
  • Caching: Decide whether repeated requests for the same page should reuse a capture. The sample uses Cache-Control: no-store; any caching policy should reflect freshness, privacy, and cost requirements.
  • Reliability: Treat target sites as variable: navigation can fail, page content can change, and visual readiness is not universal. Return meaningful errors and log operational failures without exposing sensitive URL data unnecessarily.

Frequently Asked Questions

Can I use this screenshot route with a static Next.js export?

No. A request-time screenshot needs a server runtime and a runnable browser; use a server-capable deployment instead.

Does network idle guarantee that every page is ready for a screenshot?

No. It is a navigation condition, not a universal visual-stability guarantee. Wait for a condition tied to the target page when deterministic output matters.

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.

Leave a Reply

Your email address will not be published. Required fields are marked *

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

More from the Wire

  1. World desk4 min
    How to Spot an AI Voice Scam Before Sending MoneyDon’t rely on how a caller sounds. Pause, call back through a known number, and verify the emergency with another trusted person before sending money.
  2. Mountain View desk4 min
    Google’s SynthID Detector: How to Check AI-Generated Images, Video and AudioGoogle’s SynthID Detector looks for an embedded watermark in supported images, video and audio. Here is what its results do—and do not—show.
  3. Redmond desk20 min
    How to create a link to File or Folder in Windows 11Windows 11 gives you several ways to point to a file or folder without moving or duplicating it. You can create a desktop shortcut,…
Recommended PC Tool
Recommended PC Tool
Windows Errors? Fix Them Before They SpreadFree repair scan
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.