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

iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more

Use Spatie Laravel Screenshot, point it at the rendered page URL, call fullPage(), and save the result: Screenshot::url('https://example.com')->fullPage()->save('full-page.png');. Without fullPage(), the package captures only the viewport. The documented defaults are a 1280×800 viewport, 2× device scale factor, PNG output, and network-idle waiting.

What this method captures

This workflow captures a rendered web page at a URL. It does not photograph your Laravel code editor, terminal, or server desktop. The browser loads the page, executes its client-side code, and produces a tall image of the scrollable document. You can use a public route, a staging URL, or another address reachable by the rendering browser.

The implementation below uses Spatie Laravel Screenshot. Its fluent API is designed for Laravel and delegates local browser work to Browsershot by default.

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

Install the package and choose a rendering driver

Local Browsershot driver

Install the Laravel package with Composer, then install its documented Browsershot dependency. The local route requires Node.js and a Chrome or Chromium binary; Browsershot uses Puppeteer to control headless Chrome.

composer require spatie/laravel-screenshot
composer require spatie/browsershot

Follow the package’s installation and setup instructions for the Node.js, Puppeteer, and Chrome/Chromium requirements on your operating system. Keep the browser executable available to the PHP process that performs the capture, including queue workers.

Cloudflare Browser Rendering driver

The package also documents a Cloudflare Browser Rendering driver. It calls Cloudflare’s hosted browser-rendering API, so the Laravel host does not need a local Node.js installation or Chrome binary. You do need a Cloudflare account and the API credentials and configuration described in the same setup guide.

Decision point Browsershot Cloudflare Browser Rendering
Where the browser runs On infrastructure you provision, through Chrome/Chromium Cloudflare’s hosted browser-rendering API
Local setup Node.js, Puppeteer/Browsershot, and Chrome/Chromium No local Node.js or Chrome binary
External dependency Your managed browser runtime A third-party API request plus Cloudflare credentials
Controls to evaluate Viewport, output format, device scale, full-page mode, and readiness waits

This is an architectural choice, not a documented performance or price comparison. Local rendering gives you control over the browser runtime; hosted rendering removes browser installation from the application host but adds account configuration and an external request.

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

Check version-specific requirements

Packagist listed spatie/laravel-screenshot 1.2.0, published March 17, 2026, with PHP ^8.3 and Illuminate Contracts ^12.0|^13.0. Those are registry details for that release, not permanent Laravel requirements. Check the locked version in your own composer.lock and the current Packagist record before upgrading.

Capture an entire page in Laravel

Minimal controller or service code

Import the facade and chain fullPage() before saving. The filename extension determines the output format.

<?php

namespace AppHttpControllers;

use SpatieLaravelScreenshotFacadesScreenshot;

class ScreenshotController extends Controller
{
    public function store()
    {
        Screenshot::url('https://example.com')
            ->fullPage()
            ->save(storage_path('app/screenshots/full-page.png'));

        return response()->json([
            'path' => 'storage/app/screenshots/full-page.png',
        ]);
    }
}

The documented one-line form is:

use SpatieLaravelScreenshotFacadesScreenshot;

Screenshot::url('https://example.com')
    ->fullPage()
    ->save('full-page.png');

Use an absolute, writable path in production. If you expose the resulting file through a download route, protect that route rather than placing private captures in a public directory.

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

Create a route

use AppHttpControllersScreenshotController;
use IlluminateSupportFacadesRoute;

Route::post('/admin/screenshots', [ScreenshotController::class, 'store'])
    ->middleware('auth');

For a recurring job, move the capture into a queued Job and let the request return immediately. The package documentation demonstrates queued screenshot generation; configure queue timeouts to allow the browser to finish loading large pages.

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

Control viewport, output, and the captured area

The customization documentation covers these options:

  • Full document: fullPage() requests the complete scrollable page. Omitting it uses the viewport-only default.
  • Viewport: use width(), height(), or size() to set the CSS viewport. The introduction documents 1280×800 and a 2× device scale as defaults.
  • Format: choose the filename extension, such as .png or .jpg. JPEG examples can include quality().
  • Element capture: use selector() to capture one element rather than the whole document.
  • Region capture: use clip(x, y, width, height) for a defined rectangle.

Examples:

// A wide full-page JPEG
Screenshot::url('https://example.com')
    ->width(1440)
    ->fullPage()
    ->quality(85)
    ->save(storage_path('app/screenshots/page.jpg'));

// One element only
Screenshot::url('https://example.com/pricing')
    ->selector('#pricing-table')
    ->save(storage_path('app/screenshots/pricing.png'));

// A fixed rectangle
Screenshot::url('https://example.com')
    ->clip(0, 0, 1200, 900)
    ->save(storage_path('app/screenshots/hero.png'));

Use fullPage() for a vertical screenshot of the entire document; use selector() or clip() when a very tall image would be wasteful.

Make dynamic pages ready before capture

The default wait is network idle (networkidle2). That is useful for ordinary pages, but it is not proof that every application has finished rendering. A page may fetch content after the initial network settles, render charts later, or reveal content only after scrolling.

The customization guide supports waiting for:

  • A particular selector that signals the page is ready.
  • A selected network-idle condition.
  • A specified duration.

Choose a readiness signal that matches your application. A fixed delay is a fallback when no reliable selector exists; it is not a guarantee that slow or failed content loaded. Verify the resulting image for your own page and add page-specific readiness logic when necessary. The available documentation does not establish universal handling for infinite scroll, scroll-triggered lazy loading, cross-origin restrictions, or bot defenses.

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

Readiness checklist

  • Use a stable “page loaded” or content selector instead of guessing a short delay.
  • Ensure authenticated routes can be reached by the rendering browser.
  • Check that fonts, images, charts, and client-side data appear in the saved file.
  • For pages that load content on scroll, consider changing the page or capture strategy; fullPage() alone is not documented as an infinite-scroll solution.

Run captures safely in production

Requests, timeouts, and queues

Browser startup and page loading can outlast a normal HTTP request. Queue the work for reports, scheduled snapshots, and user-triggered captures that do not need an immediate image response. Store the output outside the public web root unless it is intentionally public, and return a signed or authenticated download response.

Resource and storage planning

Full-page PNGs can be large, especially with a 2× device scale factor. Use JPEG when photographic compression is acceptable, set a deliberate viewport, and remove obsolete files with a scheduled cleanup job. Keep the original URL, capture time, driver, viewport, and output path in your application logs so a failed image can be diagnosed.

Security

Do not pass arbitrary user-supplied URLs to a server-side browser without an allowlist. A screenshot endpoint can otherwise become a server-side request forgery path into internal addresses. Restrict destinations, validate schemes, protect authenticated routes, and avoid logging secrets embedded in URLs.

Troubleshooting common failures

“Chrome executable not found” or a browser launch error

Cause: the Browsershot process cannot find Chrome/Chromium, or the PHP worker has a different PATH than your shell.

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

Fix: install a supported Chrome/Chromium binary, configure the executable according to the Browsershot setup instructions, and test from the same user and queue environment that runs Laravel. If you do not want a local browser runtime, select the documented Cloudflare driver and configure its credentials.

Node.js or Puppeteer errors

Cause: Node.js is missing, the Browsershot dependency was not installed, or the worker cannot execute the Node process.

Fix: install the documented Composer dependency and Node.js requirements, confirm Puppeteer can launch under the worker account, and inspect the full process error rather than only the HTTP response.

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

The image is only the visible viewport

Cause: fullPage() was omitted or the call is being made through a different code path.

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

Fix: add ->fullPage() before ->save() and verify the saved file dimensions.

Late content is missing

Cause: the default network-idle wait does not match the page’s asynchronous behavior.

Fix: wait for a reliable selector, choose the appropriate network-idle condition, or add a page-specific delay. Then inspect the output; do not assume a delay proves all content loaded.

The capture fails only in a queue

Cause: queue workers often have a different working directory, environment variables, PATH, filesystem permissions, or timeout than web requests.

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

Fix: use absolute paths, grant the worker write permission, install browser dependencies for that user, and increase the job timeout to accommodate the target page.

The page is blank or blocked

Cause: the target may require authentication, reject automated browsers, depend on unavailable network resources, or fail before rendering.

Fix: capture a reachable staging route, provide the required session configuration through the supported driver settings, inspect application and browser logs, and confirm the URL loads normally from the capture host. The package documentation does not promise bypassing bot checks or site-specific defenses.

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

Package documentation and reference links

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. A single GET request returns a PNG, JPEG, WebP, or PDF, so your Laravel app does not need to install and operate a browser for this capture.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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

cURL:

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

See the ScreenshotNeo API documentation for authentication and options.

Python:

import requests

r = requests.get(
    "https://api.screenshotneo.com/v1/shot",
    params={"access_key": "YOUR_API_KEY", "url": "https://your-laravel-app.example/page"},
    timeout=90,
)
r.raise_for_status()
open("shot.webp", "wb").write(r.content)

Node.js:

const q = new URLSearchParams({
  access_key: 'YOUR_API_KEY',
  url: 'https://your-laravel-app.example/page'
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo accepts 63 options, including full-page capture with lazy images loaded, CSS-selector element capture, device presets and custom viewports, retina scale, dark mode, PDF paper settings, custom CSS and JavaScript, click actions, selector or network-idle waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, and an OpenAPI specification. Parameter names used by other screenshot APIs also work for easier migration.

It removes cookie and consent banners, newsletter popups, and chat widgets before capture. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed; response headers identify the page verdict and whether the shot was billed. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.

The Free plan includes 1,000 shots per month with no card. Paid plans start at $5 for 3,000 shots; yearly billing gives two months free. Create a free ScreenshotNeo account to get started.

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.