ScreenshotNeo

BlogHow-to

PhantomJS: How to Take a Full Webpage Screenshot

Use PhantomJS’s webpage module and page.render() to save a full-page screenshot. Learn viewport, crop, troubleshooting, and a hosted API option.

By the ScreenshotNeo team4 October 20264 min read

Use PhantomJS’s webpage module, set page.viewportSize, then call page.render() after page.open() reports success. For a full-page render, leave page.clipRect unset. Save this as capture.js and run phantomjs capture.js:

var webpage = require('webpage');
var page = webpage.create();

page.viewportSize = { width: 1280, height: 900 };

page.open('https://example.com/', function (status) {
  if (status !== 'success') {
    console.log('Unable to load the address!');
    phantom.exit(1);
    return;
  }

  // Leave page.clipRect unset to render the whole page.
  page.render('full-page.png');
  phantom.exit();
});

The official render API documents output formats, and the clipRect API says that without a clipping rectangle, rendering processes the entire webpage. PhantomJS development is suspended until further notice, so treat it as a legacy workflow and inspect output on your target sites.

1. Full page, viewport, and crop

These settings control different things:

Setting Purpose Full-page capture
viewportSize Sets the page layout viewport, similar to the browser window. Both width and height are required. Choose the layout size you want, such as 1280 × 900. Responsive layouts can change with this size.
clipRect Sets the rectangle rasterized into the output. Leave it unset to render the full page. Setting it crops to the specified top, left, width, and height.
page.render() Writes the rendered page to a file. Use an image extension such as .png or .jpg.

For a fixed crop rather than the whole document, set page.clipRect before rendering:

page.clipRect = { top: 0, left: 0, width: 800, height: 600 };
page.render('crop.png');

A crop is not a way to enlarge the layout viewport. Change viewportSize to affect responsive layout; change clipRect to choose which rectangle appears in the output.

2. Choose an output format

The official PhantomJS rendering guide lists PNG, JPEG, GIF, and PDF output. Use the matching file extension in the render call; for example:

page.render('full-page.jpg');
page.render('page.pdf');

For a screenshot image, PNG is a straightforward choice. Check the output format your downstream tool expects, and do not label a file with an extension that does not match its intended format.

3. Handle load timing carefully

page.open() invokes its callback with success or fail. Render only after success. That status indicates the open operation succeeded; it does not prove that every site-specific asynchronous widget, lazy image, or delayed element has finished. There is no universal wait duration. If the target page fills in content after initial load, inspect the capture and adapt the readiness handling to that page’s behavior. The PhantomJS capture guide demonstrates using a callback and a short timeout for its example, not a guaranteed delay for all sites.

Do not assume PhantomJS can handle every current site. Its development is suspended, and the available documentation does not establish compatibility with modern browser features or any particular target.

4. Troubleshooting

Symptom Likely cause What to check
No output file page.open() returned fail, or the script exited before rendering. Print the status, keep rendering inside the callback, and exit after the render call.
Only part of the page appears clipRect is set. Remove the assignment to page.clipRect for a full-page render.
Unexpected mobile or desktop layout The viewport dimensions trigger a different responsive layout. Set page.viewportSize to the desired width and height before opening the page.
Late content is absent The page adds content after its initial load callback. Inspect the target’s loading behavior and add a page-appropriate readiness check or delay; verify the resulting image.
Capture differs from a current browser PhantomJS is a suspended project and may not match current site behavior. Validate against the target. If compatibility is insufficient, use a maintained browser workflow or a hosted screenshot service.

5. Performance, reliability, and cost

Rendering a long page can require more memory and time than rendering a viewport-sized crop because more content must be rasterized. Keep the viewport only as large as the layout requires, and use clipRect when the task truly needs a crop. Test representative pages and output dimensions in your own environment; the cited documentation gives no performance benchmark or universal timeout.

For repeatable runs, check the open status, ensure the output file was created, and inspect captures for missing late content. Because PhantomJS development is suspended, treat browser compatibility and future maintenance as operational risks. The research for this guide did not include runtime testing, so the example is based on the documented API rather than a claim of tested compatibility.

Running the CLI uses your own environment and browser setup. A hosted API replaces that setup with a request and has its own plan limits and billing rules. Compare the operational tradeoff against your workload rather than assuming one approach is always cheaper.

6. Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server. Its API documentation covers the request options. One GET request can return a screenshot or PDF; for example, save this as a shell command and replace the placeholder with your API key:

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

Cookie and consent banners, newsletter popups, and chat widgets are removed before capture. Bot checks, blank pages, failed loads, timeouts, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools for screenshots, page information, and PDF capture. The free plan includes 1,000 screenshots a month with no card; paid plans start at $5 for 3,000.

Sign up for 1,000 free screenshots a month, no card required.

7. FAQ

Does an unset clipRect really capture the whole page?

That is the documented behavior of PhantomJS’s page.render() API. Leave page.clipRect unset for a full-page render.

Does page.open success mean every element is ready?

It reports the open status as success or fail. It is not a guarantee that all site-specific delayed content has appeared.

Is PhantomJS still actively developed?

The official project site says development is suspended until further notice.