How to capture a website screenshot with PhantomJS on Ubuntu
Use PhantomJS on Ubuntu to open a webpage, check its load status, and save a screenshot. Includes viewport options, troubleshooting, and legacy support notes.
To capture a website screenshot with PhantomJS on Ubuntu, create a JavaScript file that opens the page with PhantomJS’s webpage module, checks whether the load succeeded, writes the image with page.render(), and exits. Save this as screenshot.js:
var page = require('webpage').create();
page.open('https://example.com', function(status) {
if (status === 'success') {
page.render('screenshot.png');
} else {
console.log('Unable to load the page.');
}
phantom.exit();
});
Run the script from the directory where you want the output file:
phantomjs screenshot.js
When PhantomJS can open the page, it writes screenshot.png to the current working directory. The page.open() callback reports success or fail; only render on success, and call phantom.exit() so the command-line process finishes. See the PhantomJS Quick Start and page.open API.
1. Confirm PhantomJS is available
PhantomJS is a legacy, headless browser executable that runs JavaScript files from the terminal. It is not a screenshot GUI. Check that the executable is on your PATH and note its version:
phantomjs --version
If the shell reports that the command is not found, PhantomJS is not installed or is not on PATH. Package availability depends on the Ubuntu release. The Ubuntu package evidence available for this guide is specific to Focal, whose manpage records version 2.1.1+dfsg-2ubuntu1; do not assume that the package is present in the default repositories on another release. Check the package sources for your own release before choosing an installation method. The PhantomJS repository is archived, and its README says development is suspended.
2. Create and run the capture script
- Open a terminal and change to the directory where you want
screenshot.png. - Create
screenshot.jswith the code above. Replacehttps://example.comwith the page to capture. - Run
phantomjs screenshot.js. - Check for the image in the same current working directory from which you ran PhantomJS.
The callback reports whether opening the URL succeeded; it does not prove that every image, font, or late-running page script has finished rendering. PhantomJS is suspended software, so modern site behavior and compatibility can vary.
3. Set the viewport or capture a rectangle
Set viewportSize before opening the page to control the browser viewport used for layout. Use clipRect to limit the rendered area. For example, this captures a 1024 by 768 rectangle from a page laid out at a 1280 by 900 viewport:
var page = require('webpage').create();
page.viewportSize = { width: 1280, height: 900 };
page.clipRect = { top: 0, left: 0, width: 1024, height: 768 };
page.open('https://example.com', function(status) {
if (status === 'success') {
page.render('viewport.png');
} else {
console.log('Unable to load the page.');
}
phantom.exit();
});
The viewport controls the page’s browser layout; the clip rectangle selects the output region. If you omit clipRect, the render behavior depends on the page and PhantomJS rendering setup. The official screen-capture guide demonstrates setting both values.
4. Choose the output format
The filename extension normally determines the image format. The render API documents PDF, PNG, JPEG, BMP, and PPM; GIF support depends on the Qt build. For ordinary screenshots, use .png or .jpg.
- PNG: use
.pngfor lossless output. Its quality option controls compression, not visible image quality. - JPEG: use
.jpgfor lossy output. The documented quality range is 0–100, with a default of 75. - PDF: use
.pdfwhen a document output is needed; PDF layout has different expectations from a viewport screenshot.
See the page.render API for format and quality details. If a PNG appears to have a transparent background, the page may not set one. The PhantomJS FAQ explains that the page controls its background; when appropriate, set a white background in the page before rendering.
5. Handle failed loads and incomplete pages
The minimal script handles a failed open by logging a message and exiting without writing an image. This is appropriate when a missing or unusable capture should not be mistaken for a valid screenshot. For automated runs, check whether the expected output file exists and inspect the command’s output when it does not.
A successful page.open() status only indicates that the page opened successfully according to PhantomJS. It does not guarantee that a single-page application has finished rendering, that lazy-loaded content has appeared, or that every remote asset loaded. PhantomJS is archived and may not handle current JavaScript or browser features. If a page depends on modern browser APIs, use a maintained browser automation setup or an API that performs the capture remotely.
6. Troubleshooting
| Symptom | Likely cause | What to check or do |
|---|---|---|
phantomjs: command not found |
The executable is missing or not on PATH. | Check phantomjs --version and your Ubuntu release’s package availability. The cited Ubuntu package evidence is for Focal only. |
| No screenshot file appears | The page open failed, the script was not run from the expected directory, or PhantomJS could not write there. | Read the terminal output, confirm the URL opens, check the current directory and its write permissions, and verify the output filename. |
| The image is blank or incomplete | The site may render content after the open callback, rely on unsupported browser features, or load assets late. | Check whether the page depends on modern JavaScript or delayed content. PhantomJS is suspended; a newer browser automation tool may be required. |
| The screenshot has unexpected dimensions | The viewport controls layout, while the clip rectangle controls the captured region. | Set page.viewportSize before page.open(); set page.clipRect to the desired rectangle. |
| The background looks transparent | The page may not define a background color. | Set a background color through the page when appropriate, as described in the FAQ. |
| JPEG looks too compressed | JPEG uses lossy compression; PhantomJS documents a default quality of 75. | Use a higher JPEG quality setting supported by page.render(), or choose PNG if you need lossless output. |
7. Performance, reliability, and cost
This workflow runs a local headless browser process for each command. Capture time depends on the target page, its assets, and the environment; no fixed runtime is guaranteed. For repeatable captures, keep the URL and viewport consistent, run from a writable directory, and treat a failed load or missing output as a failed job.
PhantomJS itself has no per-screenshot service charge in this workflow, but you maintain the executable and its compatibility with Ubuntu and the websites you capture. The project is archived and development is suspended, so it is a poor fit for new workflows that need ongoing browser compatibility. Ubuntu package availability is release-specific.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server from Yorker Media. One GET request returns an image or PDF. See the ScreenshotNeo API documentation for parameters and options.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://example.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://example.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
- Cookie banners are accepted and more than 60 known consent platforms, newsletter popups, and chat widgets are removed before capture; each step can be turned off.
- Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed. Response headers report the page verdict and billing status.
- An MCP server exposes
take_screenshot,get_page_info, andcapture_pdffor Claude, Cursor, and other MCP clients. - The free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots.
Sign up for 1,000 free screenshots a month with no card.
FAQ
Where does PhantomJS save the screenshot?
It saves to the path passed to page.render(). A relative path such as screenshot.png is relative to the current working directory where you ran the command.
Can I use PhantomJS on every Ubuntu release?
Do not assume so. The package evidence cited here applies to Ubuntu Focal; verify availability for your own release and confirm the executable with phantomjs --version.
Is PhantomJS still maintained?
No. Its official repository is archived, and the project README says development is suspended.


