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

Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.

If a PhantomJS screenshot shows fallback text instead of a web font, first determine whether the font request failed, the capture ran before the font and layout were ready, or the deployed PhantomJS/WebKit environment cannot use that font. A successful page navigation does not guarantee that every font loaded. Log resource requests and page errors, verify the CSS face and font URL, then add a bounded readiness wait supported by your actual PhantomJS build. If the request succeeds but the font still does not appear, check the font format and host environment. PhantomJS development is suspended, so migration may be the sensible long-term fix for a workflow you still maintain.

Why PhantomJS screenshots show fallback fonts

PhantomJS renders pages with WebKit. Its screen-capture example calls page.render() from the page.open() callback, which is a reasonable starting point, but that callback alone does not prove that a remote font request has finished or that layout has applied the intended face. A screenshot can therefore capture the page after navigation succeeds but before its typography is ready. See the PhantomJS screen-capture guide.

There are three distinct failure classes to separate:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
  • The font was never requested. CSS may not match the element, the face name or weight may be wrong, or page logic may not have applied the relevant styles.
  • The request failed or was late. The font URL may be inaccessible, blocked, slow, or affected by network, TLS, server, or access configuration; the screenshot may also happen before it finishes.
  • The resource arrived but did not render as intended. The font format, face declaration, old QtWebKit behavior, or host font environment may be involved.

Diagnose in that order. Changing the wait time cannot fix a bad URL or an unsupported font, and installing a system font cannot fix a screenshot taken too early.

Log font requests, timeouts, and page errors

Start by saving diagnostics from the same PhantomJS executable and host environment that produce the bad image. PhantomJS documents resource callbacks, request sniffing, resource timeouts, and page-side error logging in its troubleshooting guide and WebPage settings reference.

This minimal diagnostic script logs requests and responses, reports resource timeouts and JavaScript exceptions, and renders after navigation. It does not claim that navigation completion means fonts are ready; use it to establish what the page actually did before adding a readiness condition.

var page = require('webpage').create();
var system = require('system');
var url = system.args[1];
var output = system.args[2] || 'shot.png';

page.settings.resourceTimeout = 15000;
page.onResourceRequested = function (request) {
  console.log('REQUEST ' + request.id + ' ' + request.url);
};
page.onResourceReceived = function (response) {
  if (response.stage === 'end') {
    console.log('RESPONSE ' + response.status + ' ' + response.url);
  }
};
page.onResourceTimeout = function (request) {
  console.log('TIMEOUT ' + request.id + ' ' + request.url);
};
page.onError = function (message, trace) {
  console.log('PAGE ERROR ' + message);
  trace.forEach(function (item) {
    console.log('  ' + item.file + ':' + item.line);
  });
};

page.open(url, function (status) {
  console.log('OPEN ' + status + ' phantomjs=' + phantom.version.major + '.' +
    phantom.version.minor + '.' + phantom.version.patch);
  if (status !== 'success') {
    phantom.exit(1);
    return;
  }
  window.setTimeout(function () {
    page.render(output);
    console.log('WROTE ' + output);
    phantom.exit();
  }, 1000);
});

Save the console output with the failing capture. The one-second delay is only an example of a bounded wait, not a guarantee that a slow font has completed. Adjust the resource timeout to the workflow and use a readiness signal where the actual runtime supports one.

What’s actually slowing this PC down?

Pick the symptom - the matching free tool is one click away.

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

Interpret the logs

  • If no request for the expected font appears, inspect the stylesheet, selector, media conditions, face name, weight, and style. Confirm the captured element actually uses the face.
  • If the request appears and times out or returns an error, investigate the exact URL and the environment’s network access, TLS, server response, or access restrictions. A successful HTML response does not imply that a separate font request succeeded.
  • If the request completes successfully but the screenshot uses fallback text, continue to the readiness, font format, and host-environment checks below.
  • If the page reports JavaScript errors, determine whether a failed script prevented styles or content from being applied. A font request issue and a JavaScript exception are separate clues.

Also run phantomjs --version and confirm which executable the job invokes. The official troubleshooting guide warns that multiple installed versions can cause confusion; local and CI runs may not be using the same binary.

Rank #2
Sale
HTML and CSS: Design and Build Websites
  • HTML CSS Design and Build Web Sites
  • Comes with secure packaging
  • It can be a gift option

Wait for font loading before rendering

Use a bounded wait rather than rendering immediately after page navigation. A fixed delay is easy to add but is inherently a timing compromise: too short and a slow resource can still be pending; too long and every capture pays the delay. Prefer a page-side readiness condition if the deployed runtime exposes the needed API, and retain a timeout so a broken page cannot block the job indefinitely.

Feature-check the modern Font Loading API

Modern browsers expose document.fonts, a FontFaceSet. MDN documents that document.fonts.ready fulfills when loading and layout operations for used fonts are complete: MDN: Document.fonts. However, PhantomJS uses an older QtWebKit runtime. Do not assume that every PhantomJS build implements this API; check the actual executable before relying on it.

For a build in which the API is present, a page-side polling function can report readiness or hit a deadline:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
function waitForFonts(timeoutMs, done) {
  var started = Date.now();
  var timer = setInterval(function () {
    var fonts = page.evaluate(function () {
      return document.fonts ? {
        supported: true,
        status: document.fonts.status
      } : { supported: false };
    });

    if (!fonts.supported) {
      clearInterval(timer);
      done('unsupported');
      return;
    }
    if (fonts.status === 'loaded') {
      clearInterval(timer);
      done('ready');
      return;
    }
    if (Date.now() - started >= timeoutMs) {
      clearInterval(timer);
      done('timeout');
    }
  }, 100);
}

This checks the API’s status; it is not a universal compatibility promise. Verify support and behavior on your target pages. If your build does not expose document.fonts, use request logs plus a bounded delay or an application-controlled readiness signal that your runtime supports. In either case, log whether the capture proceeded because fonts were ready, because a fallback path was used, or because the deadline expired.

Verify the CSS face and the rendered element

Once timing and request evidence are available, inspect the declaration and the page element together. A valid font URL alone is insufficient if the page asks for a different family or weight.

  • Check the @font-face family name against the computed family requested by the element.
  • Check the declared font-weight and font-style against the text being captured. A face declared for one weight may not satisfy a request for another.
  • Check that the stylesheet containing the face is loaded and applies in the captured viewport and page state.
  • Confirm the font URL is the one expected for the deployed environment and that the resource request reaches it.
  • Inspect whether the element is actually using the intended face rather than an inherited or overridden family.

If a request succeeds but the image still shows fallback typography, compare the font format and CSS face definition with the specific PhantomJS/QtWebKit build. The available evidence does not establish one universally compatible format or a single configuration that fixes every build.

Check system fonts and reproduce the production host

A remote request is not the only environment dependency. If the rendering stack relies on host-installed fonts, verify that the intended font is installed and discoverable on the operating system and container that run PhantomJS. Reproduce against that same environment; a developer laptop and a Linux CI image can differ.

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

A discussion in PhantomJS issue 10373 includes a Linux-specific report involving a remote webfont in PDF output. One commenter reported that installing the font’s TTF files in /usr/share/fonts/truetype and running fc-cache -fv allowed PhantomJS to use the installed face. Another commenter said upgrading dependencies resolved their case. These are reports from particular setups, not a guaranteed fix for screenshots generally. Treat font installation as an environment-specific test, not the default remedy for every missing web font.

Rank #4
Sale
Web Design with HTML, CSS, JavaScript and jQuery Set
  • 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

Choose a fix that matches the evidence

What the logs show Best next step Trade-off
No expected font request Correct the stylesheet, face declaration, selector, or page state so the element requests the intended face. Requires correcting page configuration; extra waiting will not help.
Font request fails or times out Fix the URL or the network, TLS, server, or access condition; retain timeout diagnostics. May require changes outside the screenshot script.
Request succeeds, but capture is early Wait for a runtime-supported readiness condition or use a bounded delay with useful timeout logging. A delay adds latency and is less precise than a real readiness signal.
Request succeeds and the font still falls back Check face format and definitions, then test host font availability on the production-equivalent environment. The reported Linux font-install workaround is environment-specific.
Workflow needs ongoing browser compatibility Compare maintained renderers against your font, CSS, waiting, deployment, and diagnostics needs. Migration takes work; PhantomJS development is suspended.

The PhantomJS project home page states that development is suspended. For a new or actively maintained workflow, compare a maintained browser renderer on the same representative pages and deployment image. Check supported font formats and CSS, explicit resource or font waiting, host-font configuration, reproducible containers, and debugging output. No particular replacement’s feature matrix is established here, so test against your own pages rather than assuming compatibility.

Or skip the browser setup

If you want an API rather than maintaining a local PhantomJS setup, ScreenshotNeo is a website screenshot API and MCP server. For this font issue, it is an alternative capture path, not a claim that every font-rendering difference disappears. Its one-call API returns an image or PDF:

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

See the ScreenshotNeo API documentation for request options. The service accepts and removes cookie/consent banners, newsletter popups, and chat widgets before capture; those steps can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients. The Free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 shots.

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

Sign up for ScreenshotNeo’s free plan: 1,000 screenshots a month, no card required.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Troubleshooting common outcomes

The page opens successfully, but the font is absent from the logs

Check whether the stylesheet loaded, whether its media rules apply at the capture viewport, and whether the target element requests that family and face. Log the full requested URL; do not infer font loading from the navigation status.

The font request is present but times out

Use the timeout callback to identify the exact URL and compare access from the PhantomJS host with the environment where the page works. Check network, TLS, server response, and access restrictions. Increase the resource timeout only if a legitimate slow response is expected; it does not repair a permanently unreachable URL.

The request completes, but the screenshot is inconsistent

Record the PhantomJS version, operating system/container, request completion, and capture timing for both good and bad runs. Confirm whether the actual executable supports the Font Loading API before using it as a gate, and compare the font format and face declaration on the target runtime.

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

It works locally but fails in CI or PDF output

Reproduce in the same container and check host-font availability if the rendering stack depends on local fonts. The Linux font-install report is a lead to test, not proof that installing TTF files will fix your configuration. Keep resource and JavaScript error logs with the output.

A wait makes captures slower without fixing the font

Stop extending the delay blindly. Return to the request and CSS evidence: a longer wait cannot make an incorrect face name, missing request, inaccessible URL, or incompatible rendering setup correct. Use a deadline and make timeout outcomes visible in logs.

Frequently asked questions

Does PhantomJS support document.fonts.ready?

Do not assume so. It is a modern browser API, and support must be verified in the exact PhantomJS build you run.

Does installing a TTF on Linux always fix PhantomJS web fonts?

No. The cited issue discussion records one Linux-specific report; it is not a general guarantee.

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

Is PhantomJS still maintained?

No. The project home page says development is suspended, which is a reason to evaluate a maintained renderer for new or actively maintained workflows.

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.