Appearance
PDF like on screen: settings that just work
You want a PDF that looks like what you see in the browser: everything loaded, backgrounds and colors printed, no missing content. Here’s a ready-to-use request body that works in most cases. Copy it, replace the URL (and add your API key), and you’re good to go.
One body that does it all
- Loads the page fully — waits until the network is idle (
networkidle0). - Waits for your content — optional
waitForSelectorso SPAs and async content are ready. - Prints backgrounds —
printBackground: trueso CSS backgrounds and colors appear in the PDF. - Screen-like rendering —
emulateMediaType: "screen"so the PDF matches how the page looks on screen (not print CSS).
Use this with the PDF sync or PDF direct route.
json
{
"page": {
"goto": {
"url": "https://your-page.com/your-document",
"options": {
"waitUntil": ["networkidle0"]
}
},
"emulateMediaType": "screen",
"waitForSelector": {
"selector": "body",
"options": { "timeout": 15000, "visible": true }
},
"pdf": {
"printBackground": true,
"format": "A4"
}
}
}
waitUntil: ["networkidle0"]— Doppio waits until there are no more than 0 network connections for 500ms. Your images, fonts and API calls have time to finish.emulateMediaType: "screen"— The page is rendered with@media screen(and no@media print), so the PDF looks like the browser view.waitForSelector— Waits forbodyto be visible (up to 15s). For SPAs or slow pages, replace"body"with a selector that appears when content is ready (e.g."#app .loaded",".report-ready").printBackground: true— Backgrounds and box-shadows are included in the PDF.
When to tweak
| Situation | What to do |
|---|---|
| Content appears after JS (SPA, dashboard) | Set waitForSelector.selector to an element that exists only when the main content is rendered (e.g. "#chart", "[data-ready]"). |
| Page sets a “ready” flag | Use waitForFunction instead of or after waitForSelector, e.g. "pageFunction": "() => window.__APP_READY__ === true". |
| You want print styles (margins, page breaks) | Use "emulateMediaType": "print" so the browser uses @media print CSS. |
| Very long page / lazy-loaded sections | Keep networkidle0; if some content only loads when in view, add a waitForSelector (or waitForFunction) that targets an element at the bottom or a “loading complete” indicator. |
Minimal “no surprises” example
If you don’t need to wait for a specific selector, this is the smallest body that still loads the page fully and prints like the screen:
json
{
"page": {
"goto": {
"url": "https://your-page.com/your-document",
"options": { "waitUntil": ["networkidle0"] }
},
"emulateMediaType": "screen",
"pdf": { "printBackground": true }
}
}
For more options (margins, paper size, timeout, etc.) see Common params and PDF params.
Dark theme / background
Sites that use a class on html for dark mode (e.g. html.dark) or prefers-color-scheme often render in light mode in headless Chrome, because no theme is forced. So the PDF can have a white or light background even with printBackground: true. That’s the page’s behavior in that context, not an API bug. To get a dark PDF, the page would need to force dark mode (e.g. always add the class, or detect the render context).