Use chromedp to control Chrome from Go, wait for the page to be ready, and call Chrome DevTools Protocol’s Page.printToPDF method. It returns PDF bytes that your program can write to a file. For a simple URL-to-file job, Chrome’s headless command line can print a page without a Go browser workflow.
Choose the Go workflow or Chrome’s command line
Both approaches use Chrome’s print pipeline; the useful difference is how much control your program needs.
As an Amazon Associate I earn from qualifying purchases.
| Approach | Best fit | Control and configuration | Lifecycle |
|---|---|---|---|
| Chrome CLI | A shell job that prints a URL directly to a file. | Command-line flags set capture timing and suppress the built-in header and footer. | Your process invokes Chrome as an external command. |
| Go with chromedp | A Go application that must navigate, interact with the page, or coordinate browser actions. | Go calls the CDP print method and can set its paper, margin, orientation, header/footer, page-range, and other options. | Go manages browser and tab state through chromedp contexts. |
This is a comparison of the documented interfaces, not a performance benchmark. Chrome’s CLI documentation says that --print-to-pdf saves the target page as output.pdf in the current working directory. Chrome Headless command-line reference
Recommended Free Tools
Install Go dependencies and provide Chrome
Install chromedp and its generated CDP bindings with Go tooling, and ensure a compatible Chrome or Chromium executable is available in the environment where the program runs. Pin dependency versions in your project rather than relying on whatever version happens to be latest: generated binding signatures can change. Consult the chromedp repository for installation guidance and its headless-shell option for headless deployments; check the matching cdproto page binding for the version you pin.
#1 Best Overall
Convert a URL to PDF with Go
The example below navigates to a URL, waits for the document body to be ready, prints with background graphics and CSS page sizing enabled, then writes the returned bytes. It expects Chrome to be installed and discoverable by chromedp. Replace the example URL with your own; for generated HTML, serve it locally or navigate to an appropriate file URL.
package main
import (
"context"
"log"
"os"
"time"
"github.com/chromedp/chromedp"
"github.com/chromedp/cdproto/page"
)
func main() {
ctx, cancel := chromedp.NewContext(context.Background())
defer cancel()
ctx, cancel = context.WithTimeout(ctx, 60*time.Second)
defer cancel()
var pdf []byte
err := chromedp.Run(ctx,
chromedp.Navigate("https://example.com"),
chromedp.WaitReady("body", chromedp.ByQuery),
chromedp.ActionFunc(func(ctx context.Context) error {
var err error
pdf, _, err = page.PrintToPDF().
WithPrintBackground(true).
WithPreferCSSPageSize(true).
Do(ctx)
return err
}),
)
if err != nil {
log.Fatalf("navigate or print page: %v", err)
}
if err := os.WriteFile("output.pdf", pdf, 0644); err != nil {
log.Fatalf("write PDF: %v", err)
}
}
The print call’s generated Go signature can vary with the pinned binding version; confirm its return values and builder methods in that version’s page.go. The CDP method is Page.printToPDF, documented as printing a page as PDF. Chrome DevTools Protocol Page domain
Load generated HTML instead of a remote page
If your Go program generates the markup, write it to a temporary HTML file and navigate Chrome to its file URL, or serve it from a local HTTP endpoint and navigate to that endpoint. A local server is often preferable when the page expects relative assets, application routes, or browser-origin behavior. Ensure referenced stylesheets, fonts, images, and scripts are reachable before printing.
Wait for the page your application actually needs
WaitReady("body", ...) checks that the body is ready; it does not prove that a single-page application has finished rendering, that remote fonts loaded, or that images and asynchronous data have arrived. Wait for an application-specific selector or state when available, for example a report container your page renders only after its data is ready. A generic sleep is not a reliable readiness test. Chrome’s CLI offers timing controls, but those do not establish a universal readiness condition for every page.
Set print layout and PDF options
Use print CSS to design the document and CDP parameters to control the print job. Page.printToPDF supports portrait or landscape orientation, paper dimensions, margins, scale, page ranges, header and footer templates, background printing, and related settings. Its protocol reference also documents CSS page-size preference, tagged PDF generation, document outlines, and stream transfer mode. Check the protocol and the matching Go binding for the exact field names and availability in your pinned versions.
- Paper and orientation: Set paper dimensions or choose landscape when the content is wider than it is tall.
- Margins and scale: Tune these when content clips or when you need a predictable printable area.
- Headers and footers: Configure templates when you want page metadata; the generated binding defaults to not displaying them.
- Backgrounds: The generated binding defaults to not printing background graphics; enable them if the design relies on colored blocks or background images.
- CSS page sizing: Use
@pageand@media printfor document-authored print layout. With CSS page sizing not preferred, the protocol says content is scaled to fit the paper size; enabling preference lets CSS page size inform the output. - Page ranges: Request selected pages when you do not need the entire document; validate the syntax against the protocol binding version you use.
The protocol binding defaults include portrait orientation, no displayed header or footer, no print backgrounds, and PreferCSSPageSize set to false. Explicitly set the options your output requires rather than assuming screen styles automatically match print output.
Print a URL with Chrome’s headless CLI
For a one-off conversion or shell workflow, run Chrome directly:
chrome --headless --print-to-pdf https://developer.chrome.com/
Chrome writes output.pdf in the current working directory. To suppress the date/time header and URL/page-number footer, add --no-pdf-header-footer. The CLI also supports --timeout, which sets a maximum wait before capture even if loading is ongoing, and --virtual-time-budget, which fast-forwards time-dependent page code for capture. These flags control timing; they are not proof that a particular app has completed all asynchronous work. Chrome documents that older versions may require --print-to-pdf-no-header instead of --no-pdf-header-footer. Chrome Headless command-line reference
Or skip the browser setup
If you need a one-call page capture rather than a Go-managed print workflow, ScreenshotNeo is a website screenshot API and MCP server. Its documented GET endpoint accepts a URL and can return an image or PDF. Example request:
Rank #4
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 API documentation for request options and PDF configuration. ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; these steps can be turned off. Bot checks/CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and responses identify the page verdict and billing status in headers. An MCP server exposes take_screenshot, get_page_info, and capture_pdf for AI agents. The free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.
Sign up free for 1,000 screenshots a month, with no card required.
Quick wins for a faster PC:
Fix the driver behind crashes, sound loss and screen glitchesFind Drivers →Repair Windows errors before they cause bigger problemsFix Now →Scan for outdated or missing drivers - takes under a minuteDriver Scan →Troubleshoot common conversion problems
- Chrome cannot be launched: Confirm a compatible Chrome/Chromium executable is installed and available to chromedp in the runtime environment. In container deployments, use the project’s documented headless-shell option if appropriate.
- Navigation or printing times out: Check that the target is reachable from the machine running Chrome and that its resources are not stalled. Increase the operation deadline only when the workload needs it; use a page-specific readiness condition rather than assuming a longer wait solves incomplete rendering.
- The PDF is blank or missing content: Verify the page actually rendered in that environment and wait for the relevant application state, fonts, images, or data before printing. A body-ready check alone may be insufficient.
- Colors or backgrounds are absent: Enable print backgrounds with
WithPrintBackground(true)and inspect the page’s print CSS. - Paper size or scaling looks wrong: Check the CSS
@pagerules andPreferCSSPageSizechoice, then adjust paper dimensions, margins, or scale. - Unexpected header or footer appears: Set the print method’s header/footer options explicitly, or use the CLI’s
--no-pdf-header-footerflag. - The output file cannot be written: Check the working directory, permissions, and output path; handle file-write errors separately from browser errors.
- The Chrome connection disappears: A lost browser connection can cancel the chromedp context. Check browser process health and ensure contexts are not canceled before the print action completes.
Reliability, performance, and cost considerations
Every conversion launches or uses a real browser and waits on page behavior, so workload time depends on navigation, scripts, resources, and the page’s readiness condition; the cited documentation does not establish a universal conversion speed or resource requirement. Reuse and lifecycle decisions should be made for your application’s concurrency and isolation needs, with explicit timeouts and error handling around navigation, printing, and file output.
On Linux, chromedp says it kills Chrome child processes it started when the program finishes. Its context also carries browser and tab state, and a lost browser connection can cancel that context. Defer cancellation and keep the context alive until all browser actions and PDF output collection have completed. chromedp repository and FAQ
Best Value
Frequently asked questions
Does headless Chrome need a graphical desktop?
The Chrome CLI example uses headless mode, and chromedp documents a headless-shell option for headless environments. Deployment still needs a compatible browser executable and a runtime configuration that can launch it.
Can I use print CSS and CDP settings together?
Yes. Print CSS authors the document’s intended print layout, while CDP options control the browser’s print operation. The CSS page-size preference setting determines whether CSS page sizing is preferred over fitting content to the configured paper size.
Windows Errors? Fix Them Before They Spread
Repair common Windows errors and clear accumulated junk for a smoother, more stable PC - no reinstall needed.Free scan · no reinstallOutdated Drivers Are Slowing You Down
One free scan finds every outdated or missing driver and matches the right update for your exact hardware.Free scan · exact hardware matchIs a fixed delay enough to ensure a complete PDF?
No universal delay guarantees completion across sites. Wait for an application-specific readiness signal wherever possible; CLI timing flags likewise do not certify that all asynchronous rendering has finished.
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.




