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

Use Puppeteer from a NestJS service: inject a shared Chromium browser, open a page for each capture, navigate to the target URL, wait for the content you need, and return the screenshot bytes. The example below uses nestjs-puppeteer and takes a full-page PNG; the exact integration imports can vary with the package version you install.

Set up Puppeteer in a NestJS application

You can manage the browser yourself with Puppeteer or use a Nest integration package to make a browser available through dependency injection. This example uses nestjs-puppeteer. Its maintainers list compatibility with Node.js >=20, NestJS ^10 or ^11, and Puppeteer ^22, ^23, or ^24; check the package documentation when choosing versions or upgrading.

  1. Install the integration and its compatible NestJS and Puppeteer dependencies using the package manager and versions appropriate to your application.
  2. Register the browser module in the application module with PuppeteerModule.forRoot({ headless: true }).
  3. Inject the browser into a provider and create a page for each capture.

The integration README says headless: true selects Chrome’s new headless mode; headless: 'shell' selects the separate legacy chrome-headless-shell binary. Refer to the nestjs-puppeteer documentation for the exact module imports and setup for your installed version.

Capture a full-page screenshot in a NestJS service

This service navigates to a URL, waits for the network to become quiet according to Puppeteer’s networkidle2 condition, and returns full-page screenshot bytes. It closes the page in a finally block so navigation or capture errors do not leave that page open.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.
import { Injectable } from '@nestjs/common';
import { InjectBrowser } from 'nestjs-puppeteer';
import type { Browser } from 'puppeteer';

@Injectable()
export class ScreenshotService {
  constructor(@InjectBrowser() private readonly browser: Browser) {}

  async capture(url: string): Promise<Uint8Array> {
    const page = await this.browser.newPage();
    try {
      await page.goto(url, { waitUntil: 'networkidle2' });
      return await page.screenshot({ fullPage: true });
    } finally {
      await page.close();
    }
  }
}

The Nest package’s import names and injectable objects depend on the integration you choose. Both nestjs-puppeteer and nest-puppeteer document injectable browser-related objects; the latter also demonstrates navigation with waitUntil: 'networkidle2'. Check the documentation for the package actually installed rather than mixing their setup examples.

Expose the bytes from an HTTP route

A controller can return the service result as an image response. Set the content type to match the format you requested; Puppeteer’s default screenshot format is PNG.

import { Controller, Get, Query, Res } from '@nestjs/common';
import type { Response } from 'express';
import { ScreenshotService } from './screenshot.service';

@Controller('screenshots')
export class ScreenshotController {
  constructor(private readonly screenshots: ScreenshotService) {}

  @Get()
  async capture(@Query('url') url: string, @Res() response: Response) {
    const image = await this.screenshots.capture(url);
    response.type('png').send(Buffer.from(image));
  }
}

Register the controller and service in a Nest module, and use the HTTP adapter type that matches your application. Do not expose an unrestricted URL parameter on a public endpoint: the service needs validation and access controls before it can safely fetch user-supplied addresses.

Choose a wait condition that fits the page

No single navigation condition proves that every site’s visual content is complete. A page can render its main content after network activity settles, keep polling indefinitely, or load images only when they approach the viewport. Choose the condition based on what must appear in the screenshot.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.
  • networkidle2 is a practical starting point for pages that settle after navigation. It does not guarantee that delayed client-side rendering, fonts, or lazy images are ready.
  • Use page.waitForSelector() when a known element indicates that the content you need has rendered.
  • Use a short explicit delay only when the target has a known rendering delay that cannot be tied to a selector. Delays make capture time less predictable.
  • For pages that load images lazily, use a full-page capture and consider scrolling through the page before the screenshot so image-loading triggers run.

For example, place a selector wait after navigation when the page’s key content is identified by a stable selector:

await page.goto(url, { waitUntil: 'networkidle2' });
await page.waitForSelector('main article');
const image = await page.screenshot({ fullPage: true });

A selector wait can time out if the selector is wrong, hidden behind a consent dialog, or only added after user interaction. Treat it as a page-specific readiness check, not a universal definition of “fully loaded.”

Control dimensions, format, and capture scope

Set a predictable viewport

Choose viewport dimensions before navigation if the page’s responsive layout matters. A desktop-width viewport and a mobile-width viewport can produce entirely different page structures.

await page.setViewport({ width: 1440, height: 900, deviceScaleFactor: 1 });
await page.goto(url, { waitUntil: 'networkidle2' });

Set deviceScaleFactor explicitly when you need consistent pixel dimensions across environments. A higher scale factor creates a denser image and may increase output size.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.

Capture full page, a specific region, or another format

  • { fullPage: true } captures beyond the visible viewport. Extremely tall pages can take longer and produce large files.
  • For a single element, wait for the element and use its handle’s screenshot method. This avoids capturing unrelated page content.
  • Use Puppeteer’s screenshot options to select JPEG or WebP where supported, and tune quality for lossy formats. PNG is appropriate when lossless output is required.
  • For a PDF rather than an image, use Puppeteer’s PDF API; page size, margins, and print layout are separate from screenshot settings.

See the Puppeteer Page.screenshot() reference for screenshot options and return types.

Choose between puppeteer and puppeteer-core

The main difference is who supplies the browser. The Puppeteer installation guide says the puppeteer package downloads Chrome for Testing, while puppeteer-core does not download a browser and is intended for a browser you manage or a remote connection.

Choice Browser management Best fit Deployment consideration
puppeteer Puppeteer downloads its compatible Chrome for Testing. Local development or a deployment where the application can install and run that browser. The download adds substantial installation weight. Puppeteer’s guide lists approximate browser download sizes of 170 MB on macOS, 282 MB on Linux, and 280 MB on Windows, as recorded by Puppeteer maintainers in 2026.
puppeteer-core You provide an executable path, browser channel, or remote browser connection. A browser already managed by your infrastructure or a separately hosted Chromium service. You must configure and maintain the browser connection or binary yourself.

Use the Puppeteer installation guide for browser installation details and Puppeteer configuration documentation for externally managed browser configuration. In containers and CI, confirm that the browser installation scripts ran and that the runtime image includes the libraries and permissions Chrome needs.

Make capture jobs safer and more reliable

Validate URLs and constrain access

If a client can supply the destination URL, validate the scheme and host and block access to internal services, loopback addresses, and cloud metadata endpoints. Otherwise, a screenshot endpoint can become a server-side request forgery path. Apply request limits and authorization as well; browser automation can consume significant CPU and memory.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft

Reuse the browser, isolate each job

Launching a browser for every screenshot adds startup work. A Nest provider can hold a browser for the application’s lifetime, while each job gets a fresh page or isolated browser context. Close pages and contexts when work completes, and close the browser during application shutdown. Avoid sharing cookies or authenticated page state between unrelated users.

Handle timeouts and failures deliberately

Set navigation and selector timeouts according to your service’s request budget. Catch navigation failures, timeouts, and browser-launch errors at the application boundary and return an appropriate HTTP error rather than an empty image. Consider moving long captures to a job queue so an HTTP client does not have to hold a connection open.

Budget deployment size and concurrency

Each active page uses browser resources, so cap concurrent captures and monitor memory under realistic page loads. Full-page captures of long pages and high device scale factors can raise memory and response-size requirements. If your deployment cannot accommodate a browser binary, a managed or remote browser can centralize browser lifecycle, but adds an external service dependency and its own latency and cost.

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

Troubleshoot common capture problems

  • Browser executable not found: With puppeteer, confirm the install step downloaded Chrome for Testing. With puppeteer-core, configure the managed executable or remote connection explicitly.
  • Chrome fails to launch in CI or a container: Check that required system libraries, browser permissions, and sandbox configuration are appropriate for the environment. If package-manager scripts were blocked, follow Puppeteer’s documented manual browser installation steps.
  • Screenshot is blank or missing content: Wait for the page’s specific content selector, inspect navigation errors, and verify that the target does not require interaction or authentication.
  • Lazy images are absent: Scroll through the page before capturing, then wait for relevant images to load. A completed navigation alone does not trigger every lazy-loading behavior.
  • Navigation never reaches network idle: Some pages maintain long-lived requests. Use a selector that marks the content you need, or choose a different navigation wait strategy rather than waiting indefinitely.
  • Image dimensions differ between runs: Set viewport width, height, and device scale factor explicitly, and ensure the same browser version and font environment are used.
  • Pages leak state across captures: Do not reuse a page between unrelated jobs. Close pages reliably and use isolated browser contexts where cookies or local storage must not be shared.

Or skip the browser setup

If you need a screenshot endpoint rather than Chromium inside your NestJS deployment, ScreenshotNeo accepts a URL in one GET request and returns an image or PDF. For a WebP capture:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
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 the API options and authentication details. It removes cookie and consent banners, newsletter popups, and chat widgets before capture; bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Its MCP server lets AI agents use screenshot tools, and the free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots. Sign up for the free plan.

Frequently asked questions

Can I return a screenshot directly from a NestJS controller?

Yes. Send the screenshot bytes in the response and set the matching content type, as in the controller example. For large captures or slow target pages, a background job endpoint may be a better fit than holding an HTTP request open.

Does full-page capture automatically load every lazy image?

No. Full-page capture expands the capture area, but lazy-loading behavior depends on the page. Scroll through the page and wait for the images you need before taking the screenshot.

Which NestJS Puppeteer package should I use?

Choose one integration and follow its own documented imports and version compatibility. Do not combine provider decorators or module configuration from different packages without verifying they match.

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

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.