Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Yes, wkhtmltopdf can convert an Angular route to PDF—but only when the route is reachable, its JavaScript and data have finished loading, and the generated HTML uses features supported by wkhtmltopdf’s older Qt WebKit engine. Angular’s default client-side rendering can otherwise produce a PDF containing only the application shell. Serve the built app, wait for an application-specific readiness signal, and test the exact route, assets, fonts and binary used in production.
What wkhtmltopdf is—and why Angular needs extra care
wkhtmltopdf converts a URL or HTML file to PDF with Qt WebKit. The official downloads page identifies 0.12.6 as the stable series, released June 11, 2020. Its GitHub repository was archived on January 2, 2023. That age matters: modern Angular bundles, CSS and browser APIs may not behave like they do in current Chrome or Firefox.
Angular normally renders on the client. The initial response can contain an app shell, while JavaScript bootstraps the application, resolves the route and fetches data. A converter that captures too early records the shell instead of the finished document. wkhtmltopdf enables JavaScript, but its default JavaScript delay is only 200 milliseconds—an arbitrary pause, not proof that Angular is ready.
What’s actually slowing this PC down?
Pick the symptom - the matching free tool is one click away.
There are three practical architectures:
- Served client-rendered route: build Angular, serve the browser output, and convert the URL after a readiness condition.
- SSR or prerendered route: generate HTML containing the required content before conversion.
- Maintained browser automation: use a current browser engine when the page depends on modern JavaScript, CSS or complex asynchronous behavior.
Approach 1: convert a served client-rendered route
1. Build and serve the Angular application
Build the application with your normal production configuration. Angular’s build process compiles TypeScript and emits the configured browser output. Serve that output from a web server; wkhtmltopdf must be able to reach the route and every script, stylesheet, image, font and API endpoint it uses.
#1 Best Overall
For a route such as /reports/42, verify it in the same network environment as the converter. If the route requires authentication, provide an authenticated, narrowly scoped endpoint or session mechanism rather than exposing private credentials in a command line that other users can read.
2. Add a page-specific readiness signal
Set window.status only after route data, images and any required rendering work are complete. The hook is an application decision; it must match your actual loading path.
declare global {
interface Window { status: string; }
}
// In the component or service that knows the PDF content is ready:
window.status = 'pdf-ready';
Do not set the value during the initial component construction if an HTTP request, resolver, lazy module or image still has to finish. If several pieces load independently, set it after all required observables or promises complete.
The Tool Desk
Outbyte Driver Updater FREEScan for outdated or missing drivers - takes under a minuteDriver Scan →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Rank #2
3. Invoke wkhtmltopdf
wkhtmltopdf
--window-status pdf-ready
--javascript-delay 5000
--enable-javascript
https://app.example.com/reports/42
report-42.pdf
--window-status waits for the browser page’s status value. The delay is a fallback for code that cannot expose a readiness signal; increase it only as far as your measured worst case requires. A long fixed delay still cannot guarantee completion when an API hangs.
For diagnostics, run with a visible log and inspect the exit status. Confirm that the command’s user can resolve DNS, reach the application and call its APIs. A route that works in your desktop browser may fail in a locked-down container.
Approach 2: convert SSR or prerendered Angular HTML
Angular supports server-side rendering (SSR) and static prerendering. SSR produces rendered HTML for an incoming request; prerendering emits route HTML at build time. Either can reduce the amount of client bootstrapping wkhtmltopdf must perform.
Rank #3
When this is a good fit
- The PDF route is known ahead of time or can be rendered deterministically.
- The required data can be embedded or fetched while producing the server response.
- Your styles, fonts, images and links resolve from the converter’s environment.
Inspect the actual response sent to wkhtmltopdf. “SSR enabled” does not automatically mean that user-specific data, authenticated content or late client requests are present. If the HTML is complete but styling is absent, check absolute versus relative URLs, base paths and font accessibility.
Recommended Free Tools
Approach 3: use a current browser engine
The wkhtmltopdf project status describes its Qt/WebKit base as old and points readers toward Puppeteer for dynamic JavaScript sites. A maintained browser automation renderer is worth investigating when your Angular page uses modern syntax, dynamic imports, complex CSS, canvas, web fonts or timing-sensitive components.
This is a compatibility choice, not a universal performance verdict. Compare candidates against your own route, browser bundle, data access and PDF requirements. The project status also mentions WeasyPrint and commercial Prince for controlled report generation; those tools have different HTML and CSS support models and should be evaluated against a representative document.
Rank #4
Security and local-file access
Treat the input page, JavaScript and resources as a security boundary. The project warns that processing untrusted HTML or JavaScript with wkhtmltopdf can permit a complete server takeover. Sanitize or strictly constrain input, isolate the conversion process, run with least privilege and restrict outbound network access where possible.
In 0.12.6, local-file access is blocked by default. If a controlled document genuinely needs local assets, allow only the specific directory:
wkhtmltopdf
--allow /srv/pdf-assets/report-42
file:///srv/pdf-assets/report-42/index.html
report-42.pdf
Avoid broadly re-enabling file access as a convenience. Confirm that every permitted path is non-writable by untrusted users.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Common failures and fixes
Blank shell or missing Angular content
- Confirm the URL is the final route, not only the server root.
- Open the route from the converter host and check that JavaScript and API requests succeed.
- Use
--window-statuswith a value set after data and required assets finish. - Check that the 200 ms default delay is not being mistaken for an application wait.
Missing images, CSS or fonts
- Use URLs resolvable from the conversion machine; verify the document’s base URL.
- Check filesystem permissions for local assets.
- For local files on 0.12.6, use a narrowly scoped
--allowpath. - Confirm the font files are installed or explicitly reachable and that the exact font fallback is acceptable.
Works locally but fails in a container
- Print the installed wkhtmltopdf version and confirm the intended patched-Qt build.
- Install the fonts your document requires.
- Verify DNS, TLS certificates, proxy settings and API egress.
- Compare environment variables, route base paths and resource permissions.
Layout differs from Chrome
Expect differences from an old WebKit engine. Reduce reliance on unsupported CSS and JavaScript only when that is practical; otherwise move the route to a maintained browser renderer. Validate page breaks, flex/grid behavior, SVG, web fonts and print-specific CSS with the production binary.
Conversion hangs or times out
- Find the request that never completes: API, image, font or third-party script.
- Make readiness depend on required resources, not on an unbounded network-idle assumption.
- Use an outer process timeout and terminate stuck workers.
- Prevent retries from creating duplicate expensive jobs.
Operational checklist
- Pin and record the wkhtmltopdf binary and patched-Qt build.
- Build Angular with the production configuration.
- Serve the route from an environment that the converter can reach.
- Exercise authentication, API calls, images, fonts and lazy-loaded modules.
- Set an explicit readiness status after required content is present.
- Convert with
--window-status; use a bounded delay only as fallback. - Compare the PDF with a current-browser reference for layout and page breaks.
- Run the worker isolated and never pass untrusted HTML without strict controls.
- Regression-test after Angular, browser-bundle, CSS, font or wkhtmltopdf changes.
Or skip the browser setup
ScreenshotNeo is a website screenshot API and MCP server when you need a clean capture without maintaining a browser worker. It accepts the cookie or consent banner like a visitor and removes more than 60 known consent platforms, newsletter popups and chat widgets before capture; each cleanup 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.
For a PDF, use its API or capture_pdf MCP tool. A one-call image example is:
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 PDF options, readiness waits, authentication, CSS and JavaScript controls, and signed webhooks. The service also provides an MCP server with take_screenshot, get_page_info and capture_pdf for Claude, Cursor and other MCP clients. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
cURL, Python and Node.js examples
cURL
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
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)
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(`${res.status} ${res.statusText}`);
const data = Buffer.from(await res.arrayBuffer());
require('fs').writeFileSync('shot.webp', data);
Frequently Asked Questions
Can wkhtmltopdf render an Angular route that requires login?
Only if the converter receives a valid authenticated session or a controlled endpoint and can reach every protected API request. Do not place reusable credentials in broadly readable command lines.
Is increasing –javascript-delay enough for Angular?
No. A delay does not prove that route resolution, asynchronous data, images or fonts have completed. Prefer a page-specific window.status value and retain a bounded fallback delay.
Should I use SSR for every Angular PDF?
No. SSR or prerendering helps when the required route data can be rendered into the response. Highly interactive or browser-dependent pages may still require a current browser renderer.
Free tools Windows power users keep installed
One-click scans. No signup required.
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.

