What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
iTechGuides is reader-supported. When you buy through links on our site, we may earn an affiliate commission. As an Amazon Associate I earn from qualifying purchases. Learn more
To capture an overlay with PhantomJS, open the page, inject the overlay into the page DOM, wait until the overlay and any asynchronous assets are ready, and call page.render(). The overlay must exist before rendering; otherwise it cannot appear in the rasterized image. Set viewportSize for the browser window and use clipRect when you need a specific capture rectangle.
What the capture sequence does
The documented PhantomJS workflow is deliberately short: create a webpage, open the URL, render from the successful open callback, and exit the PhantomJS process. The official screen-capture example demonstrates that order and lists PNG, JPEG, GIF, and PDF output.
An overlay is ordinary page content for this purpose. Add a div, apply its CSS, and append it to the document before calling page.render(). This ordering is an implementation inference from the documented open-then-render flow; the official capture page does not provide a ready-made overlay-injection script.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Complete PhantomJS example
Save the following as capture-overlay.js. It captures a 1024 × 768 viewport, adds a fixed overlay in the upper-right corner, waits briefly for asynchronous work, and writes a PNG.
#1 Best Overall
var page = require('webpage').create();
var targetUrl = 'https://example.com/';
var outputPath = 'page-with-overlay.png';
page.viewportSize = {
width: 1024,
height: 768
};
page.clipRect = {
top: 0,
left: 0,
width: 1024,
height: 768
};
page.open(targetUrl, function (status) {
if (status !== 'success') {
console.log('Unable to load the page.');
phantom.exit(1);
return;
}
page.evaluate(function () {
var overlay = document.createElement('div');
overlay.id = 'capture-overlay';
overlay.textContent = 'Overlay';
overlay.style.position = 'fixed';
overlay.style.top = '16px';
overlay.style.right = '16px';
overlay.style.zIndex = '2147483647';
overlay.style.padding = '8px 12px';
overlay.style.background = 'rgba(0, 0, 0, 0.75)';
overlay.style.color = '#fff';
overlay.style.fontFamily = 'Arial, sans-serif';
overlay.style.fontSize = '16px';
overlay.style.borderRadius = '4px';
overlay.style.pointerEvents = 'none';
document.body.appendChild(overlay);
});
// Allow fonts, images, or other overlay content to finish loading.
window.setTimeout(function () {
page.render(outputPath);
phantom.exit();
}, 250);
});
Run it with the PhantomJS command-line executable:
phantomjs capture-overlay.js
A successful run creates page-with-overlay.png in the current directory. The example checks the open status before rendering, so a failed navigation cannot silently produce an apparently valid screenshot.
Injecting an overlay that has real content
Use a high stacking order
Pages commonly establish their own stacking contexts. A large z-index helps the overlay appear above site navigation, modals, and sticky headers, although a transformed or isolated ancestor can still create a separate stacking context. Appending the overlay directly to document.body avoids inheriting most component-level stacking rules.
Choose fixed or absolute positioning
position: fixed anchors the overlay to the viewport, which is useful for a watermark, status badge, or annotation that should stay in the same corner. Use position: absolute when the annotation belongs to a document location and should move with page content. For an absolute overlay, set an appropriate positioned parent or use document coordinates deliberately.
Load external fonts or images before rendering
If the overlay references a web font, image, or data fetched by JavaScript, adding the element does not prove that its visual assets are ready. Keep the page alive with a timer or a polling function, then render only after the required selector or state is present. The 250-millisecond delay in the sample is illustrative, not a universal readiness guarantee; increase it or replace it with a condition for your page.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Insert HTML safely
For static text, assign textContent as in the sample. If you must insert markup, use a controlled string and avoid copying untrusted input into innerHTML. PhantomJS executes page JavaScript in the target origin, so treat injected code and data as part of the page’s trust boundary.
Viewport size and clipping
page.viewportSize
viewportSize controls the browser viewport used while the page lays out. Responsive breakpoints, fixed overlays, and media queries all respond to this width and height. Set it before page.open() so the page loads and lays out at the intended dimensions.
page.clipRect
The PhantomJS clipRect documentation defines this property as “the rectangular area of the web page to be rasterized when page.render is invoked.” Its fields are top, left, width, and height. The sample uses a rectangle identical to the viewport, but you can capture a smaller region by changing those values.
Rank #3
- 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
Make the rectangle large enough to include the overlay. A badge at right: 16px can be cut off if the clip width ends before the viewport edge. Conversely, a clip rectangle that starts below the overlay will intentionally exclude it.
Capturing the whole page
When clipRect is omitted, the PhantomJS screen-capture guide says that page.render processes the entire page. This is different from a viewport-only image: a full-page result can include content below the fold, while a fixed overlay may appear according to PhantomJS’s page layout and rendering behavior. Verify the resulting dimensions when the overlay is expected on every page section.
Output formats and filenames
The official guide lists PNG, JPEG, GIF, and PDF output. Use a filename extension that matches the intended format, for example page-with-overlay.jpg or page-with-overlay.pdf. PNG is usually the simplest choice for sharp text and transparency; JPEG is smaller for photographic pages but introduces compression; PDF is appropriate when the consumer needs a document rather than a raster image.
Rank #4
PhantomJS can render HTML styled with CSS as well as SVG, images, and Canvas elements, so an overlay built from normal DOM and CSS participates in the same render pass.
Adding a readiness check instead of a fixed delay
A fixed delay is easy to understand but can be too short on a slow page and waste time on a fast one. For an overlay that signals readiness, poll for a selector from PhantomJS’s outer script:
function waitFor(selector, callback, timeout) {
var start = new Date().getTime();
var timer = window.setInterval(function () {
var found = page.evaluate(function (name) {
return !!document.querySelector(name);
}, selector);
if (found) {
window.clearInterval(timer);
callback(true);
return;
}
if (new Date().getTime() - start > timeout) {
window.clearInterval(timer);
callback(false);
}
}, 50);
}
// After page.evaluate() appends the overlay:
waitFor('#capture-overlay', function (ready) {
if (!ready) {
console.log('Overlay did not appear before the timeout.');
phantom.exit(1);
return;
}
page.render('page-with-overlay.png');
phantom.exit();
}, 5000);
This checks that the element exists, not that a remote image has decoded or that a web font has painted. For those cases, expose a page-side readiness flag only after your application has completed its own loading work, then poll that flag before rendering.
Best Value
Common failures and fixes
| Symptom | Likely cause | Fix |
|---|---|---|
| No image is produced | The script was not run with the PhantomJS executable, or the process exited before rendering. | Run phantomjs capture-overlay.js, keep phantom.exit() after page.render(), and log the open status. |
| The output is blank or shows an error page | page.open() returned a status other than success, or the destination failed to load. |
Handle the status callback, print a diagnostic, and do not render a failed navigation. Check the URL from the same environment where PhantomJS runs. |
| The page is visible but the overlay is missing | The overlay was appended after rendering, appended outside the document, or hidden behind another stacking context. | Call page.evaluate() before page.render(), append to document.body, and use explicit positioning and a high z-index. |
| Only part of the overlay appears | clipRect excludes its coordinates, or the overlay extends beyond the selected rectangle. |
Expand or remove clipRect; verify top, left, width, and height. |
| Overlay text appears but its image or font is absent | Rendering occurred before asynchronous assets completed. | Wait for a page-side readiness condition or a longer, measured delay before rendering. |
| Overlay is behind a modal or header | The page created a competing stacking context. | Append directly to body, set position, assign a high z-index, and avoid placing the overlay inside a transformed component. |
| The screenshot dimensions are unexpected | Viewport dimensions and clipping dimensions were configured independently. | Set viewportSize for layout and calculate clipRect for the exact output region. |
When to use a current browser automation library
If you are free to change the implementation, the current Puppeteer Page API documents page evaluation, style insertion with addStyleTag, and screenshot capture. Its ScreenshotOptions documentation covers path, output type, fullPage, and clip. Those are documented capabilities, not a promise that a PhantomJS script can be migrated without changes: selectors, timing, browser installation, and JavaScript behavior may differ. Keep PhantomJS when compatibility with an existing script is the requirement; choose a contemporary automation library when you control the runtime and need its documented APIs.
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server. It accepts a URL in one request and returns PNG, JPEG, WebP, or PDF. For an overlay workflow, you can supply custom JavaScript and CSS through the API rather than maintaining a PhantomJS process. It also supports full-page capture with lazy images loaded, CSS-selector element capture, device presets or custom viewports, retina scale, waits for selectors, delays or network idle, and click-before-capture actions.
Use the API documentation at https://screenshotneo.com/docs/ for authentication and options. A minimal cURL request is:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
The same request in 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)
And in 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}`);
const data = Buffer.from(await res.arrayBuffer());
require('fs').writeFileSync('shot.webp', data);
ScreenshotNeo removes cookie-consent banners, newsletter popups, and chat widgets before capture; each of those cleanup steps can be turned off. Bot checks and 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. An MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients.
The Free plan includes 1,000 screenshots per month with no card. Paid plans are Starter $5 for 3,000 shots, Growth $15 for 15,000, Pro $39 for 60,000, Scale $99 for 250,000, and Business $249 for 1,000,000; yearly billing gives two months free, and every feature is included on every plan. If you want to avoid installing or maintaining a browser process, sign up for the free ScreenshotNeo plan.
Frequently Asked Questions
Can I render several overlays in one image?
Yes. Create each element during the same page.evaluate() call, give them distinct IDs or classes, and wait until all required elements are ready before calling page.render().
Free tools Windows power users keep installed
One-click scans. No signup required.
Should the overlay be removed after the screenshot?
No cleanup is required when the PhantomJS process exits immediately after rendering. If you capture multiple states in one process, remove or update the prior overlay in the page before the next render.
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.

