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

Use a JavaScript-capable browser, not WeasyPrint, when the page depends on a remote script. WeasyPrint can fetch remote assets, but its renderer does not execute JavaScript. With Playwright for Python, open the page, inject the script with page.add_script_tag(url=...) when necessary, wait for the application’s own ready signal, and then call page.pdf(). Playwright prints with print media by default; call page.emulate_media(media="screen") first when the screen stylesheet is the layout you need.

Why WeasyPrint cannot load and run a JavaScript URL

Fetching a file and executing it are different operations. WeasyPrint’s Python API and default fetcher can retrieve network resources such as stylesheets, images and fonts, but the HTML-to-PDF renderer does not run page JavaScript. A script loaded with a <script src="..."> element therefore cannot build a chart, request application data, or alter the DOM before WeasyPrint creates the PDF.

That limitation is intentional: WeasyPrint is designed for static HTML and CSS rendering. Its documentation describes a model with no user interaction, JavaScript or live rendering after the document is parsed. If the final HTML already contains all content and only needs CSS layout, WeasyPrint remains a good fit. If content appears only after JavaScript executes, render the page in a browser first.

Choose the renderer that matches the page

Requirement Recommended approach Reason
Static or mostly static HTML/CSS WeasyPrint Its Python API converts HTML to PDF and can fetch referenced resources, but it does not execute JavaScript.
Data or layout created by JavaScript Playwright for Python A real browser runs the script, performs client-side requests and exposes page.pdf().
PDF/A output Verify the renderer and profile before implementation PDF/A variants prohibit JavaScript embedded as active PDF content. Running JavaScript in a browser before producing a PDF is a separate issue, but the output requirements still need checking.

Make the decision from four questions: does the source require JavaScript, how closely must browser layout be reproduced, when is the application actually ready, and which network or filesystem resources may the renderer access?

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Elebase USB to USB C Adapter for iPhone 18 Pro Max,USBC Car Charger Adapter
  • Read Before You Buy — No Video Output: These adapters support charging and USB 2.0 data transfer, but cannot transmit video signals. Except for standard USB webcams (which use USB data only), they are not compatible with HDMI/DisplayPort cables, video-capable USB-C hubs, or docking stations with video output.
  • Convert USB-A Ports to USB-C: Designed to connect USB-C earphones, cables, flash drives, card readers, and other USB-C accessories to standard USB-A ports. Plug-and-play with no drivers or software required.
  • Aluminum Alloy Housing: Built with a sturdy aluminum alloy shell that aids in heat dissipation and protects against daily wear and scratches. Designed to maintain a stable and secure connection.
  • Compact & Travel-Friendly: The ultra-compact design allows the adapter to stay plugged into your device without blocking adjacent ports or adding bulk, reducing wear and tear on your original USB ports.
  • 12-Month Warranty: Backed by a 12-month manufacturer warranty for peace of mind. Designed to meet strict quality control standards for reliable everyday performance.

Install Playwright for Python

  1. Create or activate a virtual environment.
  2. Install the Python package: pip install playwright.
  3. Install a browser engine: playwright install chromium. In a controlled deployment, install only the engine you use.

The examples below use Playwright’s synchronous API. They assume the target URL and injected script are trusted and that your process is allowed to reach them.

Load a JavaScript file by URL, wait for the app, and create a PDF

If the page already contains its own script tag, simply navigate to it. If it does not, add the remote file with page.add_script_tag(url=...). The call resolves when the script’s onload fires or its content has been injected; that does not prove that the application’s asynchronous rendering has finished.

from playwright.sync_api import sync_playwright

REPORT_URL = "https://example.test/report"
SCRIPT_URL = "https://example.test/app.js"
OUTPUT = "report.pdf"

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()

    page.goto(REPORT_URL, wait_until="domcontentloaded")
    page.add_script_tag(url=SCRIPT_URL)

    # Replace this with the real readiness signal used by your application.
    page.wait_for_function("window.reportReady === true")

    # Optional: use screen CSS rather than Playwright's default print CSS.
    # page.emulate_media(media="screen")

    page.pdf(path=OUTPUT, format="A4", print_background=True)
    browser.close()

window.reportReady is only an example. Your page might set a global after an API response, add a .report-complete element, or expose a different state value. Use the signal that represents completed application work rather than copying the example flag.

Wait for a DOM element instead of a global flag

page.wait_for_selector("[data-report-ready='true']", state="visible")
page.pdf(path="report.pdf", format="A4", print_background=True)

A selector is useful when you control the page markup. It is safer than a fixed sleep because the wait ends when the relevant element exists. For a page with several asynchronous phases, wait for the last phase that affects the PDF, such as charts finishing or a table reaching its final row count.

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

Handle pages that load their own script

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.goto("https://example.test/report", wait_until="networkidle")
    page.wait_for_selector("#final-report", state="visible")
    page.pdf(path="report.pdf", format="A4", print_background=True)
    browser.close()

networkidle is only a navigation heuristic. Analytics, WebSockets and polling can keep a page active indefinitely, while an application can finish rendering before the network becomes idle. Prefer an application-specific readiness check when one is available.

Rank #2
Anker USB-C Hub, 5-in-1 USB Hub for Laptops, 4K HDMI Multiport Adapter
  • 5-in-1 USB-C Hub: Experience comprehensive connectivity featuring a Power Delivery input, two USB-A 2.0 ports, a USB-A 3.0 port, and an HDMI port. (Note: The USB-C power delivery input port is only for connecting an external wall charger to power your laptop and cannot power peripheral devices.)
  • 90W Pass-Through Charging: Achieve optimal charging with 90W pass-through power to your laptop, supported by a total input of 100W, with the hub reserving 10W for operational efficiency. (Note: Wall charger not included.)
  • Quick Data Transfers: Accelerate your productivity with rapid data transfers using a high-speed 5Gbps USB 3.0 port and two 480Mbps USB 2.0 ports.
  • 4K HDMI Display: Enhance your visual experience with a hub capable of delivering 4K resolution at 30Hz in both mirror and extend modes. Please note that this hub is compatible with MacBook (macOS 12 and newer), Windows 10 and 11, ChromeOS, and laptops equipped with DP Alt Mode and Power Delivery. Note: This device is not compatible with Linux.
  • What You Get: Anker USB-C Hub (5-in-1, 4K HDMI), welcome guide, 18-month warranty, and our friendly customer service.

Control the PDF layout

Print media versus screen media

page.pdf() uses print media by default, so @media print rules apply. If the page was designed for the screen and you want those rules, select screen media before printing:

page.emulate_media(media="screen")
page.pdf(path="screen-layout.pdf", format="A4", print_background=True)

Check the result for hidden navigation, changed colors, page-break rules and responsive breakpoints. Selecting screen media does not disable PDF generation; it changes which CSS media query is active.

Common PDF options

  • path: destination filename.
  • format="A4" (or another supported paper format): standard page sizing.
  • print_background=True: include CSS background colors and images.
  • margin: provide top, right, bottom and left margins when the stylesheet needs explicit print spacing.
  • landscape=True: rotate the page orientation.
  • page_ranges: emit selected page ranges when the document is long.

Use CSS @page rules for repeatable headers, footers and page breaks, and test with the actual browser engine installed in production.

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

Make remote script loading reliable

Confirm that the script was requested

from playwright.sync_api import sync_playwright

with sync_playwright() as p:
    browser = p.chromium.launch()
    page = browser.new_page()
    page.on("console", lambda msg: print("console:", msg.type, msg.text))
    page.on("pageerror", lambda exc: print("page error:", exc))
    page.goto("https://example.test/report")
    page.add_script_tag(url="https://example.test/app.js")
    page.wait_for_selector("#final-report")
    page.pdf(path="report.pdf")
    browser.close()

Console and page-error listeners expose syntax errors, blocked requests and runtime exceptions that otherwise look like an empty PDF.

Account for cross-origin and CSP behavior

The remote URL must be reachable from the browser process. Authentication, DNS, TLS, proxy settings and a site’s content-security policy can all prevent loading. If the application needs cookies or authorization headers, create a browser context with the required state before navigation. Do not weaken security policies globally just to make an injection work; fix the deployment or serve a trusted script from an allowed origin.

Rank #3
Sale
Anker USB C Hub, 7in1 Multi-Port USB Adapter, 4K@60Hz USBC to HDMI Splitter
  • Sleek 7-in-1 USB-C Hub: Features an HDMI port, two USB-A 3.0 ports, and a USB-C data port, each providing 5Gbps transfer speeds. It also includes a USB-C PD input port for charging up to 100W and dual SD and TF card slots, all in a compact design.
  • Flawless 4K@60Hz Video with HDMI: Delivers exceptional clarity and smoothness with its 4K@60Hz HDMI port, making it ideal for high-definition presentations and entertainment. (Note: Only the HDMI port supports video projection; the USB-C port is for data transfer only.)
  • Double Up on Efficiency: The two USB-A 3.0 ports and a USB-C port support a fast 5Gbps data rate, significantly boosting your transfer speeds and improving productivity.
  • Fast and Reliable 85W Charging: Offers high-capacity, speedy charging for laptops up to 85W, so you spend less time tethered to an outlet and more time being productive.
  • What You Get: Anker USB-C Hub (7-in-1), welcome guide, 18-month warranty, and our friendly customer service.

Wait for data, fonts and images

JavaScript may finish inserting markup while charts, web fonts or images are still loading. Wait for the application’s final state and, where appropriate, verify that important images are complete in page JavaScript. A fixed delay can mask slow environments and still be too short under load, so use it only as a bounded supplement to a real readiness condition.

Security and isolation considerations

A remote script is executable code in the browser page. Restrict script origins and avoid allowing users to supply arbitrary URLs unless that is a deliberate, isolated feature. Treat the HTML, CSS and URLs as untrusted input when they come from customers.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

WeasyPrint’s security guidance warns about long renderings, high CPU or memory use, slow network requests and local-file access through file:// URLs. Apply the same defensive mindset to browser automation:

  • Run rendering in a restricted worker or container.
  • Set operation timeouts and enforce an overall job deadline.
  • Limit outbound network destinations and block access to internal services.
  • Sanitize or reject untrusted HTML and CSS.
  • Control filesystem permissions and output paths.
  • Review Chromium isolation settings. Playwright exposes a chromium_sandbox launch option whose default is false; configure isolation explicitly for your deployment rather than assuming it is enabled.

If you must use WeasyPrint for static documents, a custom fetcher can filter protocols and paths. Do not let a user-controlled document freely read local files or make unrestricted network requests.

Troubleshooting common failures

The PDF is blank or missing dynamic content

Cause: WeasyPrint rendered before JavaScript ran, or Playwright printed before the application became ready.
Fix: Move the workflow to Playwright, add the script with add_script_tag if needed, and wait for a real DOM or application readiness signal.

Rank #4
Sale
UGREEN USB to USB C Adapter Combo 4-Pack, 10Gbps USB C Converter Space Gray
  • Dual Converters, Infinite Potential:Includes 2× USB C male to USB A female adapters and 2× USB A male to USB C female adapters. Perfect for a wide range of uses—tablets with Bluetooth keyboards, expand USB ports on macbook, and more. Two different converters for all your daily needs
  • Next-Level 10Gbps & 3A Charging: No more slow 480Mbps, this usb to usb c adapter has a transfer speed of up to 10Gbps, allowing you to do more transferring in less time. This usb adapter fits both USB A and USB C charger, supporting up to 3A fast charging
  • Upgraded Exquisite Craftsmanship: With an aluminum alloy housing and metal connector, the usbc to usb adapter is extremely durable and sturdy. Rigorously tested to withstand more than 10,000 times of plugging and unplugging, ensuring long-lasting performance
  • Broad Compatible: The usb c to usb adapter widely supports all USB C/ USB A devices like laptops, tablets, cellphones, car chargers, and phone chargers. Such as compatible with MacBook Pro/Air 2023/2022, Thunderbolt 4/3 Devices,Apple MagSafe Watch 9/8/7/SE/Ultra, iPad Pro 2022/2021, Samsung Galaxy S23/S20/S10, and iPhone 17/16/15 Pro. Plug and play
  • Please Note: To reach 10Gbps speed, keep the cable under 3.3 ft. For USB A Male to USB C adapters, try flipping the USB C connector. USB C Male to USB A adapters support bidirectional 10Gbps transfer within 3.3 ft

add_script_tag fails or the script has no effect

Cause: DNS/TLS failure, authentication, a blocked origin, a script syntax error or a page that expects the script in a particular order.
Fix: Listen for console and page errors, verify the URL from the rendering host, load prerequisite scripts first, and inspect the browser’s network logs.

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

The script loads but data is still incomplete

Cause: The script’s onload event only indicates that the file arrived; subsequent API calls and rendering continue afterward.
Fix: Wait for the final selector, state flag or application event. Avoid relying solely on networkidle.

The PDF looks different from the browser

Cause: Print media is the default, backgrounds may be disabled, or the viewport differs from a user’s screen.
Fix: Try page.emulate_media(media="screen"), set an explicit viewport, enable print_background=True, and add print-specific CSS where the PDF should intentionally differ.

Rendering hangs or consumes excessive resources

Cause: Polling, WebSockets, an unreachable resource, a pathological document or unbounded JavaScript work.
Fix: Use explicit navigation and operation timeouts, wait on a bounded readiness condition, cancel jobs that exceed a deadline, and enforce worker CPU and memory limits.

PDF/A validation fails

Cause: The selected PDF/A profile has restrictions that ordinary browser PDFs do not satisfy, including JavaScript-related requirements.
Fix: Confirm the required profile first and choose a renderer and post-processing pipeline that explicitly supports it.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Best Value
Anker USB C Hub, 5-in-1 USBC to HDMI Splitter with 4K Display
  • 5-in-1 Connectivity: Equipped with a 4K HDMI port, a 5 Gbps USB-C data port, two 5 Gbps USB-A ports, and a USB C 100W PD-IN port. Note: The USB C 100W PD-IN port supports only charging and does not support data transfer devices such as headphones or speakers.
  • Powerful Pass-Through Charging: Supports up to 85W pass-through charging so you can power up your laptop while you use the hub. Note: Pass-through charging requires a charger (not included). Note: To achieve full power for iPad, we recommend using a 45W wall charger.
  • Transfer Files in Seconds: Move files to and from your laptop at speeds of up to 5 Gbps via the USB-C and USB-A data ports. Note: The USB C 5Gbps Data port does not support video output.
  • HD Display: Connect to the HDMI port to stream or mirror content to an external monitor in resolutions of up to 4K@30Hz. Note: The USB-C ports do not support video output.
  • What You Get: Anker 332 USB-C Hub (5-in-1), welcome guide, our worry-free 18-month warranty, and friendly customer service.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Performance, cost and operational design

Launching a browser for every document is simple but expensive compared with reusing a controlled browser process. Reuse contexts carefully, clear authentication state between tenants, and close pages after each job. Keep navigation, readiness and PDF timeouts separate so you can identify whether a failure is network, application or printing related.

Cache immutable scripts and static assets where policy permits, but do not cache user-specific responses across customers. Record the target URL, browser version, media mode, viewport, readiness condition and elapsed phases for diagnostics. Test slow API responses and missing assets, not only the fast path.

Or skip the browser setup

If you need a PDF or screenshot from a URL rather than a custom in-process rendering pipeline, ScreenshotNeo provides a website screenshot API and MCP server. It accepts consent banners before capture and removes more than 60 known consent platforms, newsletter popups and chat widgets. Bot checks, blank pages, timeouts, failed loads and cache hits are not billed, and the response identifies the page verdict and billing status in headers. Its MCP tools—take_screenshot, get_page_info and capture_pdf—can be used by Claude, Cursor and other MCP clients.

For a direct PDF request, see the ScreenshotNeo API documentation. The same endpoint can return PNG, JPEG, WebP or PDF:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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(`HTTP ${res.status}`);
const fs = await import('node:fs/promises');
await fs.writeFile('shot.webp', Buffer.from(await res.arrayBuffer()));

ScreenshotNeo includes full-page capture with lazy images loaded, CSS-selector element capture, custom JavaScript and CSS, click and wait controls, request blocking, headers, cookies, user agents, timezone and geolocation, PDF paper and margin settings, signed links, asynchronous jobs, webhooks, bulk capture for up to 100 URLs per call, caching with a chosen TTL, a usage API and an OpenAPI specification. Parameter names used by other screenshot APIs also work, which can simplify migration.

Plan Included shots Price
Free 1,000 per month No card required
Starter 3,000 $5
Growth 15,000 $15
Pro 60,000 $39
Scale 250,000 $99
Business 1,000,000 $249

Yearly billing gives two months free, and every feature is available on every plan. Start with 1,000 free screenshots a month with no card, then choose a paid plan starting at $5 for 3,000 shots if your volume requires it.

Implementation checklist

  • Confirm whether the source is static or JavaScript-dependent.
  • Use Playwright when JavaScript must execute; use WeasyPrint only when static rendering is sufficient.
  • Inject the remote script before application initialization when the page does not already include it.
  • Wait for an application-specific readiness condition.
  • Choose print or screen media deliberately.
  • Set explicit viewport, page size, margins and background behavior.
  • Constrain network, filesystem, CPU, memory and runtime for untrusted input.
  • Capture console, page-error and timeout diagnostics.
  • Validate the output against any PDF/A or accessibility requirement.

Frequently Asked Questions

Can I make WeasyPrint execute a remote JavaScript file with a custom fetcher?

No. A custom fetcher controls resource retrieval; it does not add a JavaScript runtime to WeasyPrint. Render the page in Playwright or another browser engine first.

Does Playwright’s script-load completion mean the PDF is ready?

No. It only indicates that the script file loaded or was injected. Wait for the application’s own completed state, such as a final selector or readiness flag.

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.

Can browser-rendered PDFs be used for PDF/A?

Only after checking the exact PDF/A profile and validating the generated file. PDF/A requirements can restrict JavaScript-related content and other browser-PDF characteristics.

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.