Free tools Windows power users keep installed
One-click scans. No signup required.
Yes—changing page.settings.userAgent can change a PhantomJS screenshot, but only indirectly. PhantomJS still renders with its WebKit engine. The user-agent string changes what PhantomJS sends when requesting the page and its resources; if the site returns different markup, CSS, scripts or images for that identity, the captured pixels can change. If the server returns the same response, the screenshot may be identical.
What the user-agent setting actually changes
PhantomJS exposes a per-page property named page.settings.userAgent. The setting defines the user-agent sent to the server when the page requests resources. It is a request identity, not a renderer selector.
Web servers, CDNs and application code may inspect that identity and choose a response. Common branches include a compact mobile layout, a desktop layout, different image sizes, alternate CSS, a compatibility script, or a redirect to a specialized URL. Those response differences are what can alter a screenshot. A site that serves the same content and styling to both user-agent strings will not necessarily produce a different image.
Apply the setting before the first page.open(). The PhantomJS documentation describes page settings as initial-load configuration; changing the property after opening a page does not reliably change the requests already made or the page state you are about to capture. For a new identity, use a new page (or restart the process), assign the setting, and open the URL again.
#1 Best Overall
What does not change: the rendering engine
A browser-looking string such as Chrome, Safari or an iPhone does not turn PhantomJS into that browser. The page is still rendered by the WebKit version compiled into your PhantomJS build. PhantomJS’s FAQ notes that the actual WebKit version depends on the libraries used to compile a build, so a version number in a user-agent string is not proof of support for that browser’s standards, JavaScript behavior, layout engine or graphics stack.
This distinction matters when diagnosing a mismatch. A mobile user-agent can make a server send mobile HTML, yet PhantomJS may still lack APIs or CSS behavior present in current mobile Safari or Chrome. Conversely, a desktop user-agent cannot add those APIs. Use the user-agent to test server-side content selection, not as a complete browser-emulation solution.
A controlled PhantomJS comparison
To find out whether the target site responds differently, compare two captures while changing only the user-agent. Keep the URL, viewport, crop rectangle, cookies, authentication, page actions and capture delay constant.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Complete script
var system = require('system');
var page = require('webpage').create();
var url = system.args[1] || 'https://example.com/';
var ua = system.args[2] || 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36';
// Set request identity before the initial page.open().
page.settings.userAgent = ua;
// Hold these values constant when comparing user-agents.
page.viewportSize = { width: 1366, height: 768 };
page.clipRect = { top: 0, left: 0, width: 1366, height: 768 };
page.onResourceError = function (error) {
console.log('resource error: ' + error.errorString + ' ' + error.url);
};
page.open(url, function (status) {
if (status !== 'success') {
console.log('page.open failed: ' + status);
phantom.exit(1);
return;
}
// Allow page scripts and late resources to settle. Use the same delay in every run.
window.setTimeout(function () {
page.render('capture.png');
console.log('title: ' + page.evaluate(function () { return document.title; }));
console.log('url: ' + page.url);
phantom.exit();
}, 2000);
});
Run it twice with the same URL and different strings:
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 minutePC 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 & 11phantomjs capture.js https://example.com/ 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/120.0 Safari/537.36'
phantomjs capture.js https://example.com/ 'Mozilla/5.0 (iPhone; CPU iPhone OS 17_0 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/17.0 Mobile/15E148 Safari/604.1'
The script logs the final title and URL so you can spot a redirect or an unexpected document. For deeper diagnosis, add logging to page.onResourceReceived and record response URLs and status codes. Compare page.content or selected DOM text in addition to the image. If the DOM differs, the server or client code selected different content. If the DOM is the same but pixels differ, investigate timing, animations, fonts, ads and other page-state variables before blaming the user-agent.
Keep viewport and crop independent from user-agent
page.viewportSize controls the browser viewport used for layout. page.clipRect controls the rectangle written by page.render(). Neither is changed automatically by assigning a user-agent. A site can still use viewport width, CSS media queries or JavaScript screen dimensions to choose a layout, so hold the viewport constant if your experiment is intended to isolate request identity.
Rank #3
| Variable | What it controls | How to use it in a comparison |
|---|---|---|
page.settings.userAgent |
The identity sent with page and resource requests | Change this one value between runs |
page.viewportSize |
Layout viewport dimensions | Keep width and height identical |
page.clipRect |
Region captured by page.render() |
Keep top, left, width and height identical |
| Capture timing | Which late scripts, fonts, ads or images have finished | Use the same wait strategy and delay |
| Page state | Cookies, local storage, login, clicks and form values | Start from equivalent state or document the difference |
| PhantomJS build | WebKit capabilities and quirks | Use the same executable for every run |
Changing viewport and user-agent together can be useful when reproducing a real device, but it cannot tell you which variable caused a difference. Run a user-agent-only test first, then a viewport-only test if needed.
How to interpret the result
Different markup or resources
If one run has a different navigation tree, stylesheet, image URL, redirect or script bundle, the server recognized the request identity or another state variable differed. The screenshot difference is real for that target and those conditions, but it is not evidence that PhantomJS became the named browser.
Same markup, different layout
Check viewport dimensions, device-pixel assumptions, font availability, animation state and the exact capture delay. A responsive script may read window.innerWidth rather than the user-agent. Late-loading ads and dynamically generated content can also make otherwise identical runs diverge.
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
Identical output
The site may ignore the user-agent, normalize both values to the same experience, or cache one response for both requests. Identical pixels do not prove that every site behaves this way; they only describe the URL, account state and PhantomJS build you tested.
Common failures and fixes
The page stays desktop after using a mobile user-agent
- Cause: The site may use viewport width, a cookie, JavaScript feature detection or account settings instead of the user-agent.
- Fix: Set a mobile-sized
page.viewportSize, clear or control cookies, and inspect the loaded DOM and resource URLs. Do not assume a mobile user-agent alone requests a mobile layout.
Changing the setting appears to do nothing
- Cause: The property was assigned after
page.open(), or the page had already loaded resources. - Fix: Assign
page.settings.userAgentimmediately after creating the page and before opening the URL. Run a fresh page for each value.
page.open reports failure
- Cause: DNS, TLS, network, redirect, server or PhantomJS compatibility problems.
- Fix: Log the status, final URL and resource errors; test the URL from the same machine; verify that the build can negotiate the site’s TLS configuration. A different user-agent cannot repair a failed load.
Captures differ from run to run with the same user-agent
- Cause: Dynamic ads, rotating content, animations, delayed fonts or images, random data, cookies or an inconsistent wait period.
- Fix: Use a fixed page state, disable or hide known moving elements where appropriate, wait for a selector or a consistent delay, and compare DOM snapshots before comparing pixels.
The screenshot is cropped unexpectedly
- Cause:
page.clipRectis independent of the viewport and may retain values from another test. - Fix: Set both properties explicitly for every run, or remove
clipRectwhen you intend to render the default viewport.
Performance, reliability and reproducibility
Changing a string is inexpensive; the costly part is loading and executing the page again. If you compare many identities, reuse the same test harness but create a separate page for each identity so cookies and DOM state do not leak between runs. Record the URL, user-agent, PhantomJS executable and build, viewport, clip rectangle, wait rule, timestamp and any authentication or cookie setup.
PhantomJS is a legacy headless browser. The WebKit implementation and supported standards depend on how the binary was built, so results from one build should not be generalized to another. Treat a screenshot as a site-specific observation, especially for modern applications that depend on browser APIs PhantomJS does not implement. When the goal is current-browser fidelity rather than testing server-side user-agent branching, use a maintained browser automation stack instead of trying to solve engine differences with a string.
Best Value
Or skip the browser setup
If you need a production screenshot rather than a PhantomJS experiment, ScreenshotNeo makes the capture a single HTTP request. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and whether the request was billed. It also offers custom user-agent and header controls, viewport and device presets, full-page and element captures, waiting rules, blocking, JavaScript, PDFs and an MCP server for AI agents.
See the ScreenshotNeo API documentation for parameters and response details. The same target URL can be requested from common environments:
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)
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}`);
There is a free allowance of 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots, and every feature is available on every plan. Create a free ScreenshotNeo account to try it.
FAQ
Can a user-agent string emulate touch, GPU behavior or a device’s JavaScript APIs?
No. It identifies the request to the server. Touch input, graphics behavior and API support come from PhantomJS’s WebKit build and the automation code, not from the text of the string.
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsWhat should I save so another person can reproduce the comparison?
Save the exact URL, both user-agent strings, PhantomJS binary and build information, viewport and clip rectangle, cookies or login setup, wait rule, and the captured DOM or response log alongside each image.
Frequently Asked Questions
Can a user-agent string emulate touch, GPU behavior or a device’s JavaScript APIs?
No. It identifies the request to the server. Touch input, graphics behavior and API support come from PhantomJS’s WebKit build and the automation code, not from the text of the string.
What should I save so another person can reproduce the comparison?
Save the exact URL, both user-agent strings, PhantomJS binary and build information, viewport and clip rectangle, cookies or login setup, wait rule, and the captured DOM or response log alongside each image.
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.

