# Chrome headless print to PDF (--print-to-pdf) Chrome headless print to PDF with --print-to-pdf. Save HTML or a URL as PDF, remove the header and footer, set page size, and know when to use an API. Chrome can print any page to PDF from the command line, with no Node.js or Python code. It is the quickest way to get a Chromium-quality PDF from a script or a cron job. This page covers the flags that work, what the CLI can't do, and what to use when you outgrow it. **Quick answer.** Run Chrome in headless mode with `--print-to-pdf` and the page you want. ```bash google-chrome --headless --print-to-pdf=page.pdf --no-pdf-header-footer https://example.com ``` ## The basic command This is the command for each operating system. ```bash # macOS "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome" \ --headless --print-to-pdf=page.pdf https://example.com # Linux google-chrome --headless --print-to-pdf=page.pdf https://example.com # Windows (PowerShell) & "C:\Program Files\Google\Chrome\Application\chrome.exe" ` --headless --print-to-pdf="C:\temp\page.pdf" https://example.com ``` Without a value, `--print-to-pdf` writes `output.pdf` in the current directory. Chromium and Edge accept the same flags (`chromium`, `msedge`). ## Convert a local HTML file To print a file on disk, pass a `file://` URL with an absolute path. ```bash google-chrome --headless --print-to-pdf=invoice.pdf "file://$PWD/invoice.html" ``` Relative images and stylesheets resolve against the file's folder, so keep assets next to the HTML. ## Remove the date, title and URL header and footer This flag gives you a clean page with no browser header or footer. By default Chrome prints the date and title at the top and the URL and page number at the bottom. ```bash google-chrome --headless --print-to-pdf=page.pdf --no-pdf-header-footer https://example.com ``` Older Chrome versions called this flag `--print-to-pdf-no-header`. If the header still shows up, check your Chrome version and try the old name. ## Page size, margins and landscape This section shows how to control the page layout. The CLI has no `--paper-size` or `--landscape` flag, so set the page in CSS instead and Chrome follows it. ```css @page { size: A4 landscape; /* or: Letter, 210mm 297mm, ... */ margin: 15mm; } html { -webkit-print-color-adjust: exact; print-color-adjust: exact; } /* keep background colors */ ``` This only works for HTML you control. For someone else's URL, you get whatever their print stylesheet says. ## Wait for JavaScript before printing This section helps when charts or client-side content appear after load. Chrome prints as soon as the page has loaded, so give late content time to arrive. ```bash google-chrome --headless --print-to-pdf=page.pdf \ --virtual-time-budget=10000 https://example.com/dashboard ``` `--virtual-time-budget` fast-forwards timers by up to that many milliseconds before printing. `--timeout=5000` caps the wait in real time. Neither knows when your page is actually ready. For that you need a script that waits for a condition. ## Common problems These are the issues people hit most, with the fix for each. - **Running as root in Docker.** Chrome refuses to start with its sandbox. Use a non-root user, or add `--no-sandbox` only in an isolated container. - **Old headless vs new headless.** Modern Chrome uses the "new" headless mode, and the old one ships separately as `chrome-headless-shell`. Flag behavior has changed between versions, so pin your Chrome version in CI. - **Missing fonts.** Servers often lack the fonts your HTML uses. Install them or load web fonts with `@font-face`. - **Blank or cut-off pages.** The cause is usually a fixed-height container or `overflow: hidden` on `body`. Remove them for print and use `break-inside: avoid` on blocks that shouldn't split. See [page breaks](https://html-pdf.com/html-to-pdf-page-breaks). ## When the CLI isn't enough: Puppeteer and Playwright This section shows the next step up from the CLI. For custom headers with page numbers, paper size from code, waiting on a selector, or returning bytes to a web request, you need the DevTools protocol. Here it is in Node.js. ```js import puppeteer from "puppeteer"; const browser = await puppeteer.launch(); const page = await browser.newPage(); await page.goto("https://example.com", { waitUntil: "networkidle0" }); await page.pdf({ path: "page.pdf", format: "A4", landscape: true, printBackground: true }); await browser.close(); ``` Playwright's `page.pdf()` takes nearly the same options (Chromium only). For the full walkthrough, see [Puppeteer HTML to PDF](https://html-pdf.com/puppeteer-html-to-pdf). ## Easier: one API call, no Chrome to install This section shows how to get the same output without running Chrome yourself. html-pdf.com runs headless Chromium for you and exposes the print options the CLI is missing. ```bash curl -X POST https://html-pdf.com/v1/pdf \ -H "Authorization: Bearer $HTML_PDF_KEY" \ -H "Content-Type: application/json" \ -d '{ "url": "https://example.com", "format": "A4", "landscape": true, "margin": "15mm", "media": "screen", "wait_for_expression": "window.chartsReady === true", "footer_html": "
Page of
" }' \ -o page.pdf ``` | Chrome CLI | html-pdf.com | |---|---| | `--print-to-pdf=out.pdf URL` | `{"url": "..."}` (public pages) or `{"html": "..."}` | | `--no-pdf-header-footer` | No browser header by default; add your own with `header_html` / `footer_html` | | `@page { size }` in CSS only | `format`, `width`/`height`, `landscape`, or `prefer_css_page_size` | | `--virtual-time-budget` | `wait_delay` (0 to 10 s) or `wait_for_expression` | | Local `file://` assets | Multipart upload: `index.html` plus asset files | To convert a local HTML file with its images and CSS, upload them together. ```bash curl -X POST https://html-pdf.com/v1/pdf \ -H "Authorization: Bearer $HTML_PDF_KEY" \ -F "index.html=@invoice.html" \ -F "logo.png=@logo.png" \ -F 'options={"format":"A4","margin":"15mm"}' \ -o invoice.pdf ``` Get a key, then open the link we email you to confirm your address. That adds 100 free credits (1 credit = 1 page). ```bash curl -X POST https://html-pdf.com/v1/signup -H "Content-Type: application/json" -d '{"email": "you@example.com"}' ``` Failed renders cost nothing. The full reference is in the [API docs](https://html-pdf.com/docs). Prefer to self-host? See [running Gotenberg in Docker](https://html-pdf.com/self-host-gotenberg-docker). ## FAQ ### How do I print a web page to PDF with headless Chrome? Run `google-chrome --headless --print-to-pdf=page.pdf https://example.com`. Add `--no-pdf-header-footer` to drop the date, title and URL. ### How do I set landscape or A4 with --print-to-pdf? The CLI has no paper size flag. Put `@page { size: A4 landscape; }` in your CSS, or use an API with `format` and `landscape` options. ### Does Chrome support CSS page breaks and @page margin boxes? Yes. Chromium honors `break-before`, `break-inside: avoid` and `@page` rules, and Chrome 131+ also supports `@page` margin boxes. See [page breaks](https://html-pdf.com/html-to-pdf-page-breaks). ### Is there a free API instead of installing Chrome? Yes. html-pdf.com gives you 100 free credits once, with no card, and 1 credit = 1 PDF page. Purchased credits never expire.