PhantomJS renders Hebrew correctly only when three layers agree: a usable Hebrew font is available to the PhantomJS process, the document declares right-to-left language and direction, and the shaping engine can position every mark used by the text. A missing glyph, an unsuitable fallback, or incorrect bidirectional (bidi) metadata can produce boxes, reversed punctuation, or misplaced vowel points even when the page looks fine in a normal browser.
Fix those layers in that order, then verify the actual PNG or PDF produced in the same runtime image used in production.
What must be true before PhantomJS can draw Hebrew
- The font exists in the runtime. Installing a typeface on your workstation does not install it in a container, CI runner, or server where PhantomJS runs.
- The font covers the exact characters. Check base letters, punctuation, Hebrew presentation forms if your content uses them, and niqqud (vowel points) or cantillation marks when applicable.
- The browser knows the text direction. Hebrew runs are right-to-left (RTL). Mixed Hebrew, Latin, numbers, and punctuation need explicit bidi context so the shaping engine can order each run correctly.
- Glyph positioning works at the final size. OpenType Hebrew shaping includes mark reordering and mark-to-base positioning. A font can contain a glyph while still placing a mark badly.
Fontconfig supplies system-wide font configuration and application access. Its matcher selects the closest available pattern; a successful match does not prove that the chosen family resembles the requested font or covers every character your page contains.
Build a minimal Hebrew test page first
Before changing PhantomJS options, isolate the page and test the exact strings that fail. Include unvocalized and vocalized samples, mixed-direction text, punctuation, and numbers.
#1 Best Overall
<!doctype html>
<html lang="he" dir="rtl">
<head>
<meta charset="utf-8">
<style>
@font-face {
font-family: "AppHebrew";
src: local("AppHebrew"), local("Noto Sans Hebrew");
}
body { font-family: "AppHebrew", sans-serif; font-size: 32px; }
.mixed { direction: rtl; unicode-bidi: plaintext; }
.latin { direction: ltr; unicode-bidi: isolate; }
</style>
</head>
<body>
<p>שלום עולם</p>
<p>שָׁלוֹם עוֹלָם</p>
<p class="mixed">גרסה 2.1 — example.com</p>
<p>English ליד עברית 123</p>
</body>
</html>
Use lang="he" on the document or component that owns the Hebrew. Add dir="rtl" at the same scope, then override genuinely left-to-right fragments such as a URL, a code sample, or an account number. Inspect the screenshot, not only the DOM: bidi errors often appear only in punctuation and number ordering.
Make the font available to PhantomJS
Confirm the requested family in the runtime image
Run your font checks inside the same operating-system image, user account, and container that launches PhantomJS. Font files on a developer laptop are irrelevant if the capture worker uses a clean image. Verify the family name used in CSS, then verify that the file actually contains the Hebrew characters and marks in your test page.
System fonts and web fonts
A system-installed font is straightforward when you control the capture image and need deterministic startup. A web-delivered font can keep the application bundle self-contained, but PhantomJS must successfully load it before rendering and the font license must permit server-side use. Whichever method you choose, compare the produced screenshot with the target platform; neither delivery method guarantees correct glyph coverage or mark placement by itself.
Linux installation report: treat it as a lead, not a universal recipe
A 2017 PhantomJS issue comment reports that copying TTF files into /usr/share/fonts/truetype and running fc-cache -fv made the font available for one Linux PDF case. Distribution package names, font directories, permissions, and container layouts differ, and that report concerns selectable PDF text rather than a universal screenshot guarantee. Test the equivalent procedure against your exact Linux image:
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →sudo install -m 0644 MyHebrewFont.ttf /usr/share/fonts/truetype/
sudo fc-cache -fv
fc-match "My Hebrew Family"
fc-query MyHebrewFont.ttf
If fc-match returns another family, the requested name may be wrong, the cache may not include the directory, or the font may not be installed for the account running PhantomJS. In an unprivileged container, install into a user font directory supported by that image and refresh the cache there.
Rank #2
Set direction and mixed-script boundaries explicitly
Document-level RTL
For a Hebrew-first page, use both language and direction metadata:
<html lang="he" dir="rtl">
For a component embedded in an otherwise LTR application, put dir="rtl" on the component instead of flipping the whole page. Mark embedded Latin fragments with dir="ltr" and an appropriate unicode-bidi value. Do not try to repair bidi output by reversing strings in JavaScript; that corrupts logical text and punctuation.
Mixed text, punctuation, and numbers
Test strings containing a Hebrew phrase followed by a colon, an English domain, a version number, and a dash. Assign direction to each semantic run. A screenshot in which letters look correct but the URL or number is reversed is a bidi-boundary problem, not a missing-font problem.
Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteWindows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallHandle niqqud and cantillation marks
Vowel points (niqqud), cantillation marks, and other combining characters are separate from base letters. OpenType Hebrew shaping reorders marks and positions them relative to the base glyph. Therefore:
- Confirm the chosen font contains the marks used by your content.
- Render vocalized samples at the actual production font size and device scale.
- Look for marks that disappear, collide, or drift to a neighboring letter.
- Compare a second known Hebrew-capable font to distinguish bad font data from a renderer limitation.
Increasing font-size temporarily can reveal an overlap, but it does not fix incorrect shaping. PDF paper dimensions, margins, orientation, and headers affect page layout; they do not add missing glyphs or repair bidi behavior.
Rank #3
Capture a controlled PhantomJS screenshot
Use a deterministic viewport, wait for the page to finish loading, and render only after your Hebrew test is visible. The following script is intentionally simple so a font or direction failure is easy to reproduce.
// capture.js
var page = require('webpage').create();
page.viewportSize = { width: 1280, height: 900 };
page.settings.resourceTimeout = 30000;
page.onResourceError = function (error) {
console.log('Resource error: ' + error.url + ' :: ' + error.errorString);
};
page.onConsoleMessage = function (message) {
console.log('console: ' + message);
};
page.open('https://your-site.example/hebrew-test', function (status) {
if (status !== 'success') {
console.log('Open failed: ' + status);
phantom.exit(1);
return;
}
window.setTimeout(function () {
page.render('hebrew.png');
phantom.exit(0);
}, 1500);
});
The delay is a practical fallback for pages that load CSS or fonts asynchronously; choose a value appropriate to your application and verify it does not merely hide an intermittent failure. Log resource errors so a blocked stylesheet or font request is not mistaken for a shaping defect.
Keep output settings separate from text diagnostics
Changing paperSize, margins, orientation, or page ranges can alter where text appears in a PDF, but those settings do not make PhantomJS discover a font. Diagnose glyphs and bidi in a PNG first, then tune PDF pagination.
Troubleshooting by symptom
Boxes, blank glyphs, or a visibly unrelated typeface
- Cause: The family is absent, the CSS name does not match the internal family name, or fallback lacks Hebrew coverage.
- Fix: Check the runtime font inventory and
fc-matchresult, install a Hebrew-capable font in that image, refresh the cache, and rerun the minimal page.
Hebrew letters appear but punctuation or numbers are backwards
- Cause: Mixed-direction runs have no explicit boundaries.
- Fix: Set
lang="he"anddir="rtl"for Hebrew content; isolate URLs, code, and numeric identifiers with LTR direction and test the exact string.
Vowel points are missing or misplaced
- Cause: The font lacks the combining marks, or mark-to-base positioning is not producing a usable result.
- Fix: Verify mark coverage, compare another Hebrew font, and inspect at final size. Do not assume that visible base letters prove full Hebrew support.
The font works locally but not in CI or a container
- Cause: Different image, user, cache, permissions, or network policy.
- Fix: Install and cache the font during image creation, run the font query as the PhantomJS user, and make the test page report failed font or stylesheet requests.
Intermittent failures or an old WebKit rendering difference
- Cause: The capture starts before resources settle, or PhantomJS’s old engine handles a page differently from current browsers.
- Fix: Use a bounded wait, resource logging, and a small regression image set. If the project is new, reconsider the renderer: the PhantomJS GitHub repository is archived and read-only, with GitHub listing May 30, 2023 as the archive date.
A repeatable validation checklist
- Build the exact runtime image and install the intended Hebrew font there.
- Confirm the CSS family name and fontconfig match from the PhantomJS account.
- Check base letters, niqqud, cantillation, punctuation, Latin text, and numbers.
- Set language and direction metadata at document and component boundaries.
- Capture a PNG at production viewport and device scale.
- Inspect the image for fallback, bidi ordering, and mark placement.
- Only after text is correct, configure PDF dimensions and pagination.
- Keep a small Hebrew screenshot regression set for image or renderer upgrades.
Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server when maintaining a PhantomJS font environment is unnecessary. It accepts the cookie or consent banner before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP tools—take_screenshot, get_page_info, and capture_pdf—work with Claude, Cursor, and other MCP clients.
One request returns PNG, JPEG, WebP, or PDF. The service supports full-page lazy-image loading, CSS-selector element capture, dark mode, device presets or custom viewports, retina scale, PDF paper and page options, custom CSS and JavaScript, clicks, waits, request blocking, headers, cookies, user agents, authorization, timezone, geolocation, transparent backgrounds, resizing, chosen-TTL caching, signed image links, asynchronous jobs with signed webhooks, bulk capture of up to 100 URLs per call, a usage API, an OpenAPI specification, and familiar screenshot-API parameter names.
See the ScreenshotNeo API documentation for authentication and options. Example cURL:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Scan for outdated or missing drivers - takes under a minute3Clear out junk files and repair common Windows errorsRank #4
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://your-site.example/hebrew-test -o shot.webp
Python:
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://your-site.example/hebrew-test"}, timeout=90)
open("shot.webp", "wb").write(r.content)
Node.js:
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://your-site.example/hebrew-test' }); const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
The Free plan includes 1,000 screenshots each month without a card. Paid plans start at $5 for 3,000 screenshots; yearly billing provides two months free, and every feature is on every plan. Create a free ScreenshotNeo account to try it.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Frequently asked questions
Can a PDF setting fix missing Hebrew letters?
No. Paper size and margins control layout. Font availability, glyph coverage, and shaping must be corrected in the page and runtime.
Should I reverse Hebrew strings before capture?
No. Keep text in logical Unicode order and use HTML language, direction, and bidi boundaries.
Is the reported Linux font-copy workaround guaranteed?
No. It is a 2017 issue comment describing one Linux PDF case. Validate the equivalent installation and cache refresh on your distribution and image.
Is PhantomJS a good foundation for a new capture service?
Its archived, read-only repository is a maintenance warning. For an existing job, stabilize and test it; for new work, evaluate a maintained renderer or an API that removes browser-environment management.
Best Value
- Used Book in Good Condition
Frequently Asked Questions
Can a PDF setting fix missing Hebrew letters?
No. Paper size and margins control layout. Font availability, glyph coverage, and shaping must be corrected in the page and runtime.
Should I reverse Hebrew strings before capture?
No. Keep text in logical Unicode order and use HTML language, direction, and bidi boundaries.
Is the reported Linux font-copy workaround guaranteed?
No. It is a 2017 issue comment describing one Linux PDF case. Validate the equivalent installation and cache refresh on your distribution and image.
Recommended Free Tools
Is PhantomJS a good foundation for a new capture service?
Its archived, read-only repository is a maintenance warning. For an existing job, stabilize and test it; for new work, evaluate a maintained renderer or an API that removes browser-environment management.
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.

