Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Use PhantomJS in this order: create a webpage, set viewportSize, open the URL, wait until React has committed the expected SVG and <clipPath> into the live DOM, then set clipRect and call page.render(). A successful page.open() callback only proves that the initial navigation loaded; it does not prove that React finished rendering.

If you are running PhantomJS 1.9.8, upgrade to 2.1.1 before debugging application code. That version fixed the clip-path failure reported in a real React page, although it is not a universal compatibility guarantee. PhantomJS development is suspended, so treat this as a legacy capture path and plan a move to a maintained browser renderer for new systems.

The reliable capture sequence

PhantomJS uses an old WebKit engine, but it can rasterize HTML, CSS, SVG, images and Canvas. The order of operations matters because React builds the final SVG after the initial HTML response.

  1. Create the page and configure the browser surface with viewportSize.
  2. Call page.open() and stop immediately if its status is not success.
  3. Poll a page-specific readiness condition, such as a React root, an SVG, a known clip-path ID and the disappearance of a loading marker.
  4. Inspect the live DOM with page.evaluate(). Use page.content when you need the current main-frame markup for diagnosis.
  5. Set clipRect to the rectangle you want rasterized and call page.render().

A complete PhantomJS script

Save this as capture.js, then run phantomjs capture.js https://your-site.example/page. Replace the selectors and clip-path ID with values from your application.

Free tools Windows power users keep installed

One-click scans. No signup required.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Kodak PIXPRO FZ45 Digital Camera, 16MP Point & Shoot (Black)
  • 16MP Sensor: Captures detailed photos with a CMOS sensor for everyday shooting
  • Optical Zoom: 4x optical zoom with a 27mm wide angle lens for flexible framing indoors or outdoors
  • Full HD Video: Records 1080p video for travel clips, family moments, or simple vlogging
  • Memory Support: Works with Class 10 SD, SDHC, or SDXC cards up to 512GB
  • LCD Screen and Battery: 2.7in LCD screen with 2 AA alkaline batteries for convenient on-the-go use
var page = require('webpage').create();
var system = require('system');
var address = system.args[1] || 'https://example.com';
var output = system.args[2] || 'capture.png';

page.viewportSize = { width: 1440, height: 1000 };
page.settings.resourceTimeout = 15000;
page.settings.loadImages = true;
page.settings.javascriptEnabled = true;
page.settings.userAgent = 'Mozilla/5.0 (compatible; PhantomJS capture)';

page.onError = function (message, trace) {
  console.error('page error: ' + message);
  trace.forEach(function (item) {
    console.error('  ' + item.file + ':' + item.line + ' ' + item.function);
  });
};
page.onResourceError = function (error) {
  console.error('resource error ' + error.id + ': ' + error.url + ' (' + error.errorString + ')');
};
page.onResourceTimeout = function (request) {
  console.error('resource timeout: ' + request.url);
};

page.open(address, function (status) {
  if (status !== 'success') {
    console.error('open failed: ' + status);
    phantom.exit(1);
    return;
  }

  var started = Date.now();
  var timeout = 20000;

  function probe() {
    var state = page.evaluate(function () {
      var root = document.querySelector('#root,[data-reactroot]');
      var svg = document.querySelector('svg');
      var clip = document.querySelector('clipPath');
      var loading = document.querySelector('.loading,[aria-busy=true]');
      var expected = document.getElementById('chart-clip');
      return {
        root: !!root,
        svg: !!svg,
        clip: !!clip,
        expectedClip: !!expected,
        loading: !!loading,
        ready: !!root && !!svg && !!clip && !!expected && !loading
      };
    });

    if (state.ready) {
      page.clipRect = { top: 0, left: 0, width: 1200, height: 800 };
      page.render(output);
      console.log('saved ' + output);
      phantom.exit(0);
      return;
    }

    if (Date.now() - started > timeout) {
      console.error('readiness timeout: ' + JSON.stringify(state));
      console.error(page.content);
      phantom.exit(2);
      return;
    }
    setTimeout(probe, 100);
  }

  probe();
});

The HTML entities in the listing (&& and >) become normal JavaScript operators when copied from a rendered page. If you save the source directly from this article, decode them first.

Make the readiness test match your React app

Do not use a blind delay as the primary synchronization method. A delay can capture an empty chart on a slow CI worker or waste time on a fast page. Prefer a condition that represents the finished UI.

Useful readiness signals

  • A root element such as #root or an element with data-reactroot.
  • The exact <svg>, <defs> and <clipPath> nodes expected by the component.
  • A stable ID, for example chart-clip, and a matching clip-path reference.
  • Removal of a loading element or a transition from aria-busy=true to false.
  • An application-specific marker that is set only after data fetching and layout calculation finish.

page.evaluate() runs JavaScript in the page context and returns serializable values. Keep the object small: booleans, strings and numbers are easier to inspect than DOM nodes. A fixed timeout is a reasonable fallback when the application has no marker, but keep it bounded and log the final state when it expires.

Inspect the actual DOM

When the screenshot is blank or missing the SVG, print page.content after the readiness timeout. This shows the current main-frame markup rather than only the original response. Check whether React inserted the expected nodes and whether the clip-path ID is exactly the one referenced by the rendered shape. IDs are case-sensitive, and a mismatch such as url(#ChartClip) versus url(#chart-clip) prevents the reference from resolving.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why clipPath output is often missing

The definition is not in the rendered document

Put the <clipPath> definition in the SVG document that uses it, normally under <defs>. Verify that React actually committed both the definition and the element carrying clip-path before rendering. A component that renders the shape first and adds definitions later can produce a transient un-clipped or empty frame.

Rank #2
Sale
Kodak PIXPRO FZ55-BK 16MP CMOS Sensor Camera 5X Optical Zoom 28mm Wide
  • 16MP Sensor: Captures detailed photos with a CMOS sensor for everyday shooting
  • Optical Zoom: 5x optical zoom with a 28mm wide angle lens for flexible framing indoors or outdoors
  • Full HD Video: Records 1080p video for travel clips, family moments, or simple vlogging
  • Memory Support: Works with Class 10 SD, SDHC, or SDXC cards up to 512GB
  • LCD Screen and Battery: 2.7in LCD screen and a rechargeable lithium-ion battery for on-the-go use

The reference or geometry is invalid

Confirm that the ID in clip-path='url(#id)' matches the definition exactly. Inspect the clip geometry and its coordinate system as well as the target element’s dimensions. A valid definition with a zero-sized or off-canvas geometry can look identical to a missing clip path in a raster image.

External resources change the result

Stylesheets, fonts, images and scripts can affect layout and SVG geometry. Use onResourceError and onResourceTimeout while diagnosing failures. PhantomJS exposes controls for image loading, JavaScript, local-to-remote URL access, resource timeout, user agent and web security; change only the setting implicated by the error, because broad security changes can hide a real deployment problem.

Isolate the browser engine

Create a minimal inline SVG fixture containing one rectangle, one <clipPath> and one clipped shape. If that fixture fails, the problem is likely PhantomJS/WebKit compatibility. If it succeeds, compare the production page’s React timing, CSS, external resources and URL settings.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Viewport size versus clipRect

page.viewportSize controls the browser surface on which the page lays out. It affects responsive breakpoints, SVG dimensions expressed in viewport units and the position of fixed elements. Set it before page.open() so the application renders at the intended breakpoint.

page.clipRect controls the rectangle rasterized by page.render(). It is not a CSS crop and it does not change layout. Use coordinates relative to the page’s rendered surface, and keep the rectangle within the content you intend to capture. For a full-page result, omit clipRect only when the resulting page dimensions are acceptable; otherwise calculate a deliberate rectangle after the layout is ready.

Rank #3
Sale
Digital Camera, Latest FHD 1080P Digital Camera for Teens with SD Card Anti Shake Point and Shoot Cameras Portable 16X Zoom Compact Small Cameras for Kids Boys Girls Seniors with Wrist Strap
  • Latest Digital Camera Built-in Fill Light : This compact digital camera is paired with a powerful CMOS processor and image stabilization to help you take & record the most exciting moments in 44 MP quality images & FHD 1080P quality videos anywhere, anytime. Plus, there is also a built-in fill light to help you take high quality pictures even in low light&dark settings, making this the perfect camera for all indoors/outdoors situations.
  • Long-Lasting Battery Life & 16X Digital Zoom :This point and shoot camera will retain its battery charge even after long use. The controls and functions are easy to operate making this the perfect choice for children, teens and younger. This kids camera supports 16x digital zoom, you can zoom in or out the subject by pressing the W/T button for taking still photos to zoom in or out on distant objects and capture all the details you need.
  • Multifunctional & Portable Digital Camera: This cheap digital camera is slim enough to fit in your pocket. You'll easily be able to take it with you on all your indoor/outdoor activities and adventures and ideal for beginners, children and teenagers. This kids digital camera is equipped with 20 filters, anti-shaking, self-timer, continuous shooting, date stamp, time-lapse recording, smile capture, internal MIC and speaker (recording sound videos), great for your daily photography needs.
  • WEBCAM & PAUSE FUNCTION : More than just a FHD 1080p digital camera, it also works as a webcam for video calls and vlogging. Connect the camera to the computer, press shutter and power button at the same time and the camera will automatically turn on webcam mode for all your video calling and live streaming needs. The pause function allows you to pause when seeing playback videos.
  • A Must Have Photography Device : This digital camera with SD card made from high-quality materials, this retro camera is safe and durable. Perfect for all ages to develop & improve their photographic abilities and observation skills. Our dedicated and experienced 24/7 support team is available for all after purchase troubleshooting, questions and technical help.

PhantomJS can write PNG, JPEG, GIF or PDF output. If an image unexpectedly has transparency, set an explicit page background in your CSS; when no background is supplied, PhantomJS leaves the background to the page.

Version choice and maintenance risk

A reported React capture used PhantomJS 1.9.8 and found that an SVG clip-path reference was ignored. The author reported that upgrading to 2.1.1 resolved that case. Treat this as a practical version-specific report, not proof that every clip-path issue disappears after an upgrade.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

The PhantomJS project states, “Important: PhantomJS development is suspended until further notice.” Its repository is archived and read-only, with 2.1 as the latest stable release line. Keep PhantomJS when a legacy output must remain byte-for-byte familiar, pin the binary in CI, and record its viewport, user agent and resource settings. For new capture work, evaluate a maintained Chromium-based browser or a hosted browser-rendering API against your SVG/CSS compatibility, data-isolation, reproducibility and deployment requirements.

Troubleshooting checklist

Symptom Likely cause Fix
page.open is not success DNS, TLS, redirect, server or network failure Log the status and resource errors, verify the URL from the capture host, and fix connectivity before investigating React.
PNG is blank but navigation succeeded React has not committed, JavaScript failed, or a resource timed out Poll a DOM condition, inspect page.content, enable onError and resource callbacks, and increase the resource timeout only when the page genuinely needs it.
SVG exists but the clip is ignored Wrong ID, missing definition, unsupported legacy WebKit behavior or invalid geometry Compare the ID character-for-character, keep <clipPath> in the same SVG, test a minimal fixture, and upgrade 1.9.8 to 2.1.1 where legacy use is unavoidable.
Desktop and CI captures differ Different viewport, user agent, fonts, timing or network responses Pin viewport and user agent, wait on a deterministic marker, make required resources available, and archive the PhantomJS binary.
Images or fonts are absent Image loading disabled, URL access blocked or resource timeout Confirm loadImages, inspect URL/security settings and callbacks, and serve assets from an address reachable by the capture process.
Crop is wrong clipRect coordinates do not match the laid-out page Set the viewport first, inspect the element’s position in evaluate(), then calculate the rectangle in page coordinates.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, reliability and cost considerations

Polling every 100 milliseconds is usually inexpensive compared with page loading, but use a finite deadline so a broken app cannot leave a worker running forever. Capture only after network and layout work needed for the SVG is complete; rendering repeatedly while React is still changing the tree creates nondeterministic files.

For reliable CI, pin PhantomJS 2.1.1, the operating-system image and the fonts available to the process. Log the URL, viewport, clip rectangle, readiness state, resource errors and output format. Keep a small fixture test beside the production capture so an engine regression is distinguishable from an application regression.

Rank #4
Kodak PIXPRO FZ55-RD 16MP Camera 5X Optical Zoom 28mm Wide Angle 1080p
  • 16MP Sensor: Captures detailed photos with a CMOS sensor for everyday shooting
  • Optical Zoom: 5x optical zoom with a 28mm wide angle lens for flexible framing indoors or outdoors
  • Full HD Video: Records 1080p video for travel clips, family moments, or simple vlogging
  • Memory Support: Works with Class 10 SD, SDHC, or SDXC cards up to 512GB
  • LCD Screen and Battery: 2.7in LCD screen and a rechargeable lithium-ion battery for on-the-go use

Self-hosting gives control over cookies, headers, user-agent and network access, but you own the obsolete runtime and its security updates. A maintained browser service shifts that operational work to a provider; compare its SVG/CSS support, wait controls, PDF and image formats, clipping API, CI reproducibility and data-handling terms before changing a pipeline.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Or skip the browser setup

ScreenshotNeo is a website screenshot API and MCP server for developers. It accepts a URL and returns PNG, JPEG, WebP or PDF. Before capture it accepts cookie/consent banners and removes more than 60 known consent platforms, newsletter popups and chat widgets; each cleanup step can be disabled. Bot checks, CAPTCHAs, blank pages, timeouts, failed loads and cache hits are not billed, and response headers identify the page verdict and whether it was billed.

Use the same one-call pattern from any environment (see the ScreenshotNeo API documentation):

curl -G 'https://api.screenshotneo.com/v1/shot' -d access_key=YOUR_API_KEY --data-urlencode url=https://your-site.example/report -o shot.webp

Equivalent Python:

import requests
r = requests.get('https://api.screenshotneo.com/v1/shot', params={'access_key': 'YOUR_API_KEY', 'url': 'https://your-site.example/report'}, timeout=90)
r.raise_for_status()
open('shot.webp', 'wb').write(r.content)

Equivalent Node.js:

const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://your-site.example/report' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
if (!res.ok) throw new Error(`${res.status} ${res.statusText}`);
require('fs').writeFileSync('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo also provides full-page lazy-image loading, CSS-selector element capture, dark mode, 12 device presets or custom viewports, retina scale, PDF paper sizes/margins/landscape/page ranges, custom CSS and JavaScript, pre-capture clicks, selector hiding, waits for a selector/delay/network idle, request and resource blocking, headers/cookies/user agents/Authorization, timezone and geolocation, transparent backgrounds, resizing, chosen cache TTLs, signed links, asynchronous jobs with signed webhooks, bulk capture for up to 100 URLs per call, a usage API and an OpenAPI specification. Its MCP tools—take_screenshot, get_page_info and capture_pdf—let Claude, Cursor and other MCP clients capture pages without custom browser code. Every feature is on every plan: 1,000 shots per month are free with no card; paid plans start at $5 for 3,000 shots, with yearly billing providing two months free. Start with the free ScreenshotNeo account.

Frequently Asked Questions

Can I pass the URL and output filename from a CI job?

Yes. The example reads the URL from the first command-line argument and the output path from the second, so a CI step can invoke phantomjs capture.js "$TARGET_URL" "$ARTIFACT_PATH" and retain the generated file as an artifact.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.

Why does a transparent-looking capture differ from the browser tab?

PhantomJS leaves the page background unchanged when no background is declared. Set an explicit background color on the page or capture container when the desired output must be opaque.

Is a successful status a guarantee that the screenshot is complete?

No. It describes navigation, not application readiness. React, fonts, images and late network requests can still be pending, so a DOM-based readiness check remains necessary.

Quick Recap

SaleBestseller No. 1
Kodak PIXPRO FZ45 Digital Camera, 16MP Point & Shoot (Black)
Kodak PIXPRO FZ45 Digital Camera, 16MP Point & Shoot (Black)
16MP Sensor: Captures detailed photos with a CMOS sensor for everyday shooting; Full HD Video: Records 1080p video for travel clips, family moments, or simple vlogging
$99.99
SaleBestseller No. 2
Kodak PIXPRO FZ55-BK 16MP CMOS Sensor Camera 5X Optical Zoom 28mm Wide
Kodak PIXPRO FZ55-BK 16MP CMOS Sensor Camera 5X Optical Zoom 28mm Wide
16MP Sensor: Captures detailed photos with a CMOS sensor for everyday shooting; Full HD Video: Records 1080p video for travel clips, family moments, or simple vlogging
$139.99
Bestseller No. 4
Kodak PIXPRO FZ55-RD 16MP Camera 5X Optical Zoom 28mm Wide Angle 1080p
Kodak PIXPRO FZ55-RD 16MP Camera 5X Optical Zoom 28mm Wide Angle 1080p
16MP Sensor: Captures detailed photos with a CMOS sensor for everyday shooting; Full HD Video: Records 1080p video for travel clips, family moments, or simple vlogging
$139.99

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.