The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Build the destination as a URL, encode it as the screenshot service’s url parameter, then treat the response as image bytes. In Playwright, the equivalent is different: navigate with page.goto(url) and capture the already-open page with page.screenshot(). Keeping those two steps separate prevents broken query strings, leaked credentials and screenshots of the wrong page.
First choose the screenshot model
“JavaScript screenshot API” can mean either a hosted HTTP service or a browser you operate with Playwright. The URL is supplied in a different place in each model.
| Model | Where the URL goes | Where rendering runs | Typical result |
|---|---|---|---|
| Hosted screenshot API | The request’s url parameter |
The provider’s browser infrastructure | Image bytes in the HTTP response |
| Playwright | page.goto(url) |
Your application’s browser process | A file written by page.screenshot() |
The rest of this guide shows both approaches. Use a hosted endpoint when you want to send a URL over HTTP without maintaining Chromium. Use Playwright when your application needs direct control over the browser, navigation and capture behavior.
Hosted API: construct and encode the URL
Keep the page address as a URL value rather than concatenating raw text into a query string. URL resolves relative paths correctly, and URLSearchParams percent-encodes ampersands, question marks and other reserved characters inside the destination.
Quick wins for a faster PC:
Repair Windows errors before they cause bigger problemsFix Now →Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →#1 Best Overall
- Record videos and take screenshots of your computer screen including sound
- Highlight the movement of your mouse
- Record your webcam and insert it into your screen video
- Edit your recording easily
- Perfect for video tutorials, gaming videos, online classes and more
JavaScript with fetch
const target = new URL('/article?id=42&ref=home', 'https://example.com');
const endpoint = new URL('https://screenshot-api.net/v1/screenshot');
endpoint.searchParams.set('url', target.href);
const response = await fetch(endpoint, {
headers: { Authorization: `Bearer ${process.env.SCREENSHOT_API_KEY}` }
});
if (!response.ok) {
throw new Error(`Screenshot request failed: ${response.status}`);
}
const image = Buffer.from(await response.arrayBuffer());
await import('node:fs/promises').then(fs => fs.writeFile('screenshot.png', image));
The destination becomes https://example.com/article?id=42&ref=home, while the outer request safely encodes that entire value. The documented hosted response is the rendered image itself, not JSON containing an image URL. Save the response body as binary data and use the returned content type (PNG, JPEG or another format selected by the service) when serving it.
Do not expose production keys
Make authenticated calls from trusted server-side code. A bearer header keeps the key out of the destination URL. Some screenshot services also accept a ?key= query parameter for direct image use, but query-string credentials can appear in page source, browser history, proxy logs and server logs. Reserve that form for cases where its exposure is acceptable, never for a production secret embedded in public client-side JavaScript.
When the input is user supplied
- Parse with
new URL(input)and reject malformed values before making the request. - Apply an allowlist of schemes, normally
https:and, only when required,http:. - Do not let untrusted users choose internal network addresses if your server can reach private infrastructure.
- Preserve fragments only when the target application uses them client-side; fragments are not sent in ordinary HTTP requests and may not affect server rendering.
Playwright: navigate first, capture second
With Playwright, the screenshot method does not receive the destination URL. The browser must already be on the page.
import { chromium } from 'playwright';
const target = new URL('/article?id=42&ref=home', 'https://example.com');
const browser = await chromium.launch();
const page = await browser.newPage();
try {
await page.goto(target.href, { waitUntil: 'networkidle' });
await page.screenshot({ path: 'page.png', fullPage: true });
} finally {
await browser.close();
}
page.goto() performs navigation; page.screenshot() captures the rendered page. fullPage: true extends the capture to the full scrollable document. For a viewport-only image, omit it. For a selected region, pass a clip rectangle.
Rank #2
- Works on Windows 11, 10, & 8
- Build a Professional Resume Fast with the step-by-step guide to help you create a professional resume that showcases your unique experience and skills
- ResumeMaker & Resume Maker are registered trademarks & box images and screenshots are copyrights of Individual Software Inc.
- Modern Resume Styles - Choose from 60 styles and customize any style with choice of header, colors, graphics and a photograph plus Powerful Ways to Search for Jobs
- Video Resumes & Expert Advice - View Sample Video Resumes and video resume scripts you can customize plus Email & Share Your Resume on LinkedIn, Facebook & Twitter
Capture a specific area
await page.screenshot({
path: 'chart.png',
clip: { x: 80, y: 160, width: 900, height: 500 }
});
Use clipping when the page is long but only one coordinate region matters. If the element’s position changes responsively, locate it first and derive its bounding box rather than hard-coding coordinates.
Make dynamic pages repeatable
Wait for a meaningful readiness condition instead of assuming that navigation means every widget has finished rendering.
await page.goto(target.href, { waitUntil: 'domcontentloaded' });
await page.waitForSelector('[data-chart-ready]');
await page.screenshot({ path: 'stable.png', fullPage: true });
You can also hide animated or volatile elements with stylesheet controls, disable transitions with injected CSS, or wait for a known delay when no reliable selector exists. Screenshot assertions in the Playwright test runner are separate from ordinary capture calls; they wait for consecutive captures to stabilize before comparing an expectation.
Complete JavaScript request patterns
Building URLs from route data
function articleUrl(origin, id, ref) {
const url = new URL('/article', origin);
url.searchParams.set('id', String(id));
if (ref) url.searchParams.set('ref', ref);
return url;
}
const target = articleUrl('https://example.com', 42, 'home');
const endpoint = new URL('https://screenshot-api.net/v1/screenshot');
endpoint.searchParams.set('url', target.href);
const response = await fetch(endpoint, {
headers: { Authorization: `Bearer ${process.env.SCREENSHOT_API_KEY}` }
});
Using searchParams.set() avoids hand-written escaping and correctly handles values containing spaces, ampersands or Unicode characters.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
Rank #3
- Works on Windows 11, 10 & 8
- Kids ages 6 to 12 and older kids to adults learn to type on exciting adventures outside the classroom
- Both typing programs provide rewards every step of the way and learn in English or spanish
- Teaches keyboard basics following an age appropriate typing plan
- Typing Instructor is a registered trademark & box images and screenshots are copyrights of Individual Software Inc.
Check content before writing a file
const contentType = response.headers.get('content-type') || '';
if (!contentType.startsWith('image/')) {
const message = await response.text();
throw new Error(`Expected an image, received ${contentType}: ${message}`);
}
const bytes = new Uint8Array(await response.arrayBuffer());
This check catches authentication pages, validation errors and JSON error responses that would otherwise be saved with an image filename.
Equivalent cURL, Python and Node.js calls
The following hosted-service examples use ScreenshotNeo’s endpoint. See the ScreenshotNeo documentation for the current parameter reference.
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Python
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, 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://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
await import('node:fs/promises').then(fs => fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer())));
Or skip the browser setup
ScreenshotNeo is a hosted screenshot API and MCP server. Its URL is passed as a parameter, so your JavaScript only needs to build the target and make one request:
const target = new URL('/article?id=42', 'https://example.com');
const q = new URLSearchParams({
access_key: process.env.SCREENSHOTNEO_KEY,
url: target.href
});
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`Screenshot failed: ${res.status}`);
const bytes = Buffer.from(await res.arrayBuffer());
ScreenshotNeo accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info and capture_pdf tools for Claude, Cursor and other MCP clients. The Free plan includes 1,000 screenshots per month without a card; paid plans start at $5 for 3,000 shots.
Create a free ScreenshotNeo account to get the 1,000 monthly screenshots without entering a card.
Rank #4
Troubleshooting dynamic URL captures
The target has its own query string
Symptom: parameters after the first ampersand disappear or are interpreted as parameters of the screenshot endpoint. Fix: construct the destination with URL and set it through URLSearchParams (or use cURL’s --data-urlencode). Never paste an unescaped destination into the outer query string.
The saved file is JSON or HTML
Symptom: an image filename opens as an error document. Cause: an HTTP error, authentication failure or redirect response was saved without checking it. Fix: test response.ok, inspect content-type, and log the status and response text before writing bytes.
Playwright captures a loading shell
Cause: the application renders content after navigation. Fix: wait for a stable selector, a known application event or a carefully chosen delay. Use networkidle only when the page’s background requests eventually settle.
Free tools Windows power users keep installed
One-click scans. No signup required.
Images or fonts are missing
Cause: blocked resources, cross-origin restrictions, lazy loading or a capture taken too early. Fix: wait for the relevant elements, verify resource responses in the browser, and scroll or otherwise trigger lazy content before capturing. A hosted service with full-page lazy-image loading can remove some of this browser setup.
Best Value
The API key appears in client code
Cause: the request is made directly from browser JavaScript with a query-string key. Fix: proxy the call through your server and send credentials in a protected environment. Treat any key already shipped to users as exposed and rotate it.
Reliability, performance and cost decisions
- URL generation: deterministic URL construction makes retries safe and prevents accidental captures of a default route.
- Timeouts: set a client timeout long enough for slow pages, then record the target and HTTP status when it expires.
- Binary handling: stream or buffer image bytes; do not parse a successful image response with
response.json(). - Repeatability: freeze animations, wait for readiness selectors and use consistent viewport settings when comparing captures.
- Browser ownership: Playwright gives maximum control but requires browser processes, updates and resource management. A hosted API moves that operational work to the provider.
- Billing awareness: ScreenshotNeo reports page verdict and billing status in response headers, and cache hits and failed captures are not billed under its stated rules.
FAQ
Should the URL be placed in the screenshot method?
No. In a hosted API it is the request’s url parameter. In Playwright, call page.goto(url) first; the screenshot method captures the current page.
Can I pass a relative URL?
Resolve it against a known origin with new URL(relative, origin) before sending it. A screenshot service needs an absolute destination that its renderer can request.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Outdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchWhat does a hosted screenshot response contain?
The documented response is the rendered image bytes with a matching image content type, not a JSON object containing a separate image link.
Frequently Asked Questions
Is URL encoding still needed when using JavaScript’s URL object?
Yes. Set the complete destination through URLSearchParams on the outer endpoint; this encodes the destination’s own query characters safely.
When is Playwright preferable to a hosted API?
Choose Playwright when you need application-controlled browser state, custom navigation logic or local test assertions. Choose a hosted API when you prefer an HTTP call without operating the browser.
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.
Recommended Free Tools

