Generate Print-Ready PDFs from Dynamic Pages
Challenges of PDF generation for SPAs and dynamic dashboards: automation steps before print, print CSS, wait strategies, and example payloads — with links to automation and page interaction features.
Why dynamic pages break naive PDF pipelines
Single-page applications do not ship finished HTML. They ship a shell, hydrate JavaScript, fetch JSON, and only then paint prices, charts, and disclaimers. A PDF job that fires the instant DOMContentLoaded fires will happily archive an empty spinner — technically a faithful capture of the DOM at that millisecond, but useless for finance or customer communications.
Print-ready PDFs require the same discipline as production screenshots: explicit waits, interaction steps, and often print-specific CSS. The difference is that PDFs amplify layout bugs through pagination — a slightly early capture might split a totals row across pages in embarrassing ways.
Drive the page before you print
Use an automation sequence to reach the state you want archived:
- Accept cookie banners or dismiss modals that obscure content.
- Log in with stored credentials or custom headers when the report is behind authentication.
- Expand accordions, open the correct tab, or scroll lazy sections into view.
- Wait for a network-quiet window or a known selector before calling print.
ScreenshotCenter models these as ordered steps in the same payload you already use for screenshots — see page interactions for the full vocabulary of clicks, typing, scrolling, and delays.
Print CSS and viewport strategy
Browsers honor @media print rules when generating PDFs. That is both an opportunity and a footgun. If your site hides navigation in print CSS but accidentally hides the invoice table too, your API will loyally reproduce the mistake.
Recommended practices:
- Maintain a dedicated print stylesheet or scoped print classes for documents you know will be PDF’d.
- Set viewport width close to your intended print column width so responsive breakpoints choose the same layout tier as your customers see on desktop.
- Test multi-page breaks with long tables; use
break-inside: avoidon total rows where supported.
Wait strategies that survive real sites
| Strategy | Best for | Risk |
|---|---|---|
| Fixed delay | Simple marketing pages | Too short on slow CDNs; wastes time when long |
| Selector-visible wait | SPAs with known success markers | Breaks when selectors change |
| Network idle | Data-heavy dashboards | Can stall on perpetual analytics calls |
| Hybrid (cap + selector) | Production automation | Requires tuning per template |
Combine waits with automation so you are not relying on a single magic timer. For complex flows — multi-step wizards, nested iframes (where supported), or hybrid SSR/CSR pages — document the sequence alongside your template so operations can replay captures months later.
Example shape: interact, then PDF
// Illustrative JSON — field names follow your OpenAPI schema
{
"url": "https://app.example.com/reports/quarterly",
"steps": [
{ "action": "wait", "duration_ms": 500 },
{ "action": "click", "selector": "#tab-financials" },
{ "action": "wait_for_selector", "selector": "table.qb-totals", "timeout_ms": 15000 }
],
"output": "pdf",
"format": "A4",
"print_background": true
}
Retries, timeouts, and partial failure
Dynamic dashboards occasionally time out, CDNs return 503s, or third-party scripts throw — your PDF job should distinguish transient failures (retry with backoff) from deterministic failures (bad credentials, 404 template). Log the final DOM signal you waited for; when a job fails, that log tells you whether the selector never appeared or the page errored first.
Cap total wall-clock time per job so runaway SPAs cannot occupy workers indefinitely. Surface structured error codes to your own callers so client applications can show “report still generating” versus “login expired” without parsing screenshots of error pages.
Putting it together
Dynamic PDF generation is a subset of general browser automation: you are proving that a headless Chrome instance reached the same UI state a human would before printing. Centralizing that in automation-capable infrastructure keeps your capture logic consistent whether the final artifact is PDF, PNG, or video. Start from the user journey, encode it as steps, then attach PDF parameters — not the other way around.