The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →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.
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.
#1 Best Overall
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.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallCheck 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
- 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.
Recommended Free Tools
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(), orsize()to set the CSS viewport. The introduction documents 1280×800 and a 2× device scale as defaults. - Format: choose the filename extension, such as
.pngor.jpg. JPEG examples can includequality(). - 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.
Quick wins for a faster PC:
Scan for outdated or missing drivers - takes under a minuteDriver Scan →Clear out junk files and repair common Windows errorsFree Scan →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →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.
Rank #3
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.
Do these 3 things before closing this tab:
1Fix the driver behind crashes, sound loss and screen glitches2Clear out junk files and repair common Windows errors3Scan for outdated or missing drivers - takes under a minuteFix: 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
- 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.
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.
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.
Best Value
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.Package documentation and reference links
- Laravel Screenshot introduction — drivers and documented defaults.
- Customizing screenshots — full-page mode, dimensions, formats, selectors, clipping, and waits.
- Installation and setup — Browsershot and Cloudflare configuration.
- Browsershot image creation and Browsershot introduction — Puppeteer and headless Chrome context.
- Packagist package record — version-specific requirements and release metadata.
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.
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.
Quick Recap
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.

