Short answer: fetching HTML from a URL and executing the JavaScript on that page are different operations. iText pdfHTML can download and convert HTML, but it does not evaluate JavaScript. If scripts build the page or load data after navigation, use a browser engine such as Playwright for Java, wait for an application-specific ready condition, and print the rendered page to PDF.
Choose the renderer that matches the page
Start by deciding whether the source is already complete HTML or a browser application.
| Requirement | Best-fit approach | JavaScript execution |
|---|---|---|
| Static HTML with compatible CSS | iText pdfHTML | No |
| Client-side rendering, API calls, charts, or interactive widgets | Playwright Java with Chromium | Yes, in a browser |
| Pure Java XHTML/CSS rendering | Flying Saucer core | No; script tags are ignored |
| Modern HTML5/CSS3 through Chrome | Flying Saucer’s flying-saucer-chrome-pdf artifact |
Delegated to Chrome |
These choices are not interchangeable. A converter that opens a URL can retrieve the initial response while still producing a PDF that lacks content inserted by scripts.
Browser-backed conversion with Playwright Java
Use this route when the page must run JavaScript. Playwright navigates to the URL in Chromium, allows the application to finish rendering, and then calls page.pdf().
Minimal runnable workflow
import com.microsoft.playwright.Browser;
import com.microsoft.playwright.BrowserType;
import com.microsoft.playwright.Page;
import com.microsoft.playwright.Playwright;
import com.microsoft.playwright.Response;
import java.nio.file.Paths;
public class UrlToPdf {
public static void main(String[] args) {
try (Playwright playwright = Playwright.create()) {
Browser browser = playwright.chromium().launch(
new BrowserType.LaunchOptions().setHeadless(true));
try {
Page page = browser.newPage();
page.setDefaultNavigationTimeout(30_000);
Response response = page.navigate(
"https://example.com/report",
new Page.NavigateOptions().setWaitUntil(
com.microsoft.playwright.options.WaitUntilState.DOMCONTENTLOADED));
if (response == null) {
throw new IllegalStateException("Navigation returned no response");
}
if (response.status() >= 400) {
throw new IllegalStateException("HTTP status: " + response.status());
}
// Replace this with a condition that means your application is complete.
page.waitForSelector("[data-report-ready]",
new Page.WaitForSelectorOptions().setTimeout(30_000));
page.pdf(new Page.PdfOptions()
.setPath(Paths.get("report.pdf"))
.setFormat("A4")
.setPrintBackground(true)
.setMargin(new Page.PdfOptions.Margin()
.setTop("16mm").setRight("12mm")
.setBottom("16mm").setLeft("12mm")));
} finally {
browser.close();
}
}
}
}
Install the Playwright Java dependency and the browser binary using the installation instructions for the exact Playwright release selected by your project. Do not hard-code a version here: the official API page does not establish one universal current version.
Wait for the page’s real ready state
domcontentloaded only means the initial document was parsed. If JavaScript then fetches records, renders a chart, or replaces a loading skeleton, wait for a selector, text value, URL state, or other deterministic application signal:
page.waitForSelector("#invoice-table tbody tr");
page.waitForFunction("() => window.appState && window.appState.ready === true");
page.waitForURL("**/report/complete");
Playwright exposes load and domcontentloaded navigation states. Its API documentation discourages using networkidle as a general readiness guarantee: analytics, polling, and long-lived connections can keep a page busy, while a page can become visually complete before the network becomes idle.
Print media, screen media, and PDF options
page.pdf() uses print CSS media by default. That means @media print rules, page breaks, and hidden navigation can change the result. If the design is intended for the screen, call page.emulateMedia(new Page.EmulateMediaOptions().setMedia(Media.SCREEN)) before generating the PDF. Configure paper format or explicit width and height, margins, background printing, landscape orientation, and page ranges according to the document.
The Tool Desk
Outbyte PC Repair FREERepair Windows errors before they cause bigger problemsFix Now →Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Rank #2
Use print styles deliberately: set page-break rules around invoices or chapters, ensure text remains selectable, and avoid relying on hover-only controls. If fonts or images are loaded late, include a ready condition that confirms them, or wait for a specific element whose appearance proves the content is present.
When iText pdfHTML is sufficient
iText’s documented URL pattern creates a Java URL, opens its stream, and passes that stream to HtmlConverter.convertToPdf. This retrieves the document; pdfHTML does not evaluate JavaScript. It is therefore appropriate when the response already contains the final content or when you have pre-rendered the page elsewhere.
import com.itextpdf.html2pdf.HtmlConverter;
import com.itextpdf.html2pdf.ConverterProperties;
import java.io.InputStream;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
public class StaticUrlToPdf {
public static void main(String[] args) throws Exception {
URL url = new URL("https://example.com/static-report.html");
ConverterProperties properties = new ConverterProperties();
properties.setBaseUri(url.toExternalForm());
try (InputStream html = url.openStream()) {
try (var output = Files.newOutputStream(Path.of("report.pdf"))) {
HtmlConverter.convertToPdf(html, output, properties);
}
}
}
}
The base URI is important when the HTML references relative CSS, images, fonts, or other assets. For a JavaScript application, first render with Playwright, save the resulting HTML and assets if needed, then convert that prepared input with iText—or print directly from the browser.
Cookies, authentication, and headers
A URL stream does not reproduce a browser session. If the page requires cookies, an authorization header, a CSRF token, or a user-agent-specific response, configure those explicitly in the browser context or HTTP client. Never place credentials in a URL that may be logged. Restrict outbound destinations when converting untrusted URLs to reduce server-side request-forgery and data-exfiltration risk.
Free tools Windows power users keep installed
One-click scans. No signup required.
Where Flying Saucer fits
Flying Saucer’s core renderer is a pure Java XML/XHTML and CSS 2.1 implementation. Its guide states that scripting is not supported and script tags are ignored, so it will not execute a client-side application. The project also lists a separate flying-saucer-chrome-pdf artifact that delegates PDF output to chrome-headless-shell and targets modern HTML5/CSS3. If JavaScript evaluation is required, select the Chrome-backed route and verify the Java runtime requirements for the exact artifact release: project notes indicate that 9.5.0 requires Java 11+, 9.6.0 Java 17+, and 10.0.0 Java 21+.
Production checklist
- Confirm whether the initial HTML contains the final data or scripts insert it later.
- Use a browser engine for client-side rendering; do not expect iText pdfHTML or Flying Saucer core to run scripts.
- Check the navigation response and fail clearly on HTTP errors or navigation exceptions.
- Set explicit navigation and selector timeouts rather than waiting indefinitely.
- Wait for a page-specific ready signal, not an arbitrary sleep and not universal reliance on network idle.
- Set print or screen media intentionally and define paper, margins, orientation, backgrounds, and page ranges.
- Handle browser and page lifecycle in
try/finallyor try-with-resources so failures do not leak processes. - Log URL, status, elapsed time, and the failed readiness condition without logging secrets.
- Pin and regularly update the browser/runtime versions used in deployment.
- Test pages with slow APIs, missing images, web fonts, cookie banners, redirects, and authentication.
Common failures and fixes
The PDF contains only a loading shell
The converter captured the document before client-side rendering completed, or a non-browser converter ignored the scripts. Use Playwright and wait for the table, chart, or application-ready marker.
Relative images or CSS are missing
For iText, set ConverterProperties.setBaseUri to the source document’s URL. In a browser, inspect failed requests and ensure the context can reach the asset host.
Navigation returns an error or no response
Check DNS, TLS, redirects, authentication, and the HTTP status. Increase the timeout only after identifying a slow dependency; a longer timeout cannot fix a blocked request.
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 reinstallRank #4
The PDF looks different from the website
PDF generation uses print media by default. Add print CSS or emulate screen media, then set backgrounds, margins, and page dimensions explicitly.
Dynamic content is intermittently absent
A fixed delay is fragile. Wait for a deterministic selector or JavaScript state, and make the application expose a completion marker when possible. Capture diagnostic HTML or a screenshot on failure.
Fonts or images are incomplete
Ensure the browser remains open until the ready condition, verify cross-origin access and authentication for assets, and include a condition that proves the relevant content is rendered.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Or skip the browser setup
ScreenshotNeo provides a website screenshot API and MCP server when you need a rendered capture without managing Chromium in your Java service. Its endpoint can return PNG, JPEG, WebP, or PDF. A single request is:
Do these 3 things before closing this tab:
1Repair Windows errors before they cause bigger problems2Fix the driver behind crashes, sound loss and screen glitches3Clear out junk files and repair common Windows errorsBest Value
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 documentation for the full parameter set. It can wait for a selector, delay, or network idle; run custom JavaScript; click elements; load lazy images; set cookies, headers, user agent, timezone, and geolocation; choose print settings for PDFs; block ads or resource types; capture an element; and submit asynchronous or bulk jobs.
Before capture, ScreenshotNeo can accept cookie/consent banners and remove more than 60 known consent platforms, newsletter popups, and chat widgets, with each step individually switchable. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed; response headers identify the page verdict and billing result. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients.
The Free plan includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 shots; every feature is available on every plan, and yearly billing provides two months free. Create a free ScreenshotNeo account to begin.
Which approach should you use?
Choose Playwright when JavaScript, browser APIs, authenticated sessions, or precise rendered output are essential. Choose iText pdfHTML when the HTML is static or has been pre-rendered and you want a Java conversion pipeline. Choose Flying Saucer core only for its supported XHTML/CSS subset; use its Chrome-backed artifact when you specifically need Chrome rendering. The decisive question is always whether the page’s final content exists in the fetched HTML or is produced by a browser after scripts run.
Frequently Asked Questions
Can iText pdfHTML execute JavaScript from a remote page?
No. pdfHTML can fetch and convert HTML, but it does not evaluate JavaScript. Render the page in a browser first or print it directly with a browser engine.
Is waiting for network idle enough?
Not reliably. Use a selector, URL state, text condition, or application-ready flag that represents the content you need in the PDF.
Why does Playwright’s PDF differ from the screen?
Playwright generates PDFs with print CSS media by default. Add print styles or emulate screen media and set PDF page options explicitly.
Does Flying Saucer run script tags?
Its pure Java renderer ignores scripts. The project lists a separate Chrome-backed PDF artifact for modern browser rendering.
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.

