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

Go’s net/http package handles HTTP requests and responses; it does not render HTML into PDF. For browser-quality output, pair an HTTP handler with Chromium and the Go package chromedp, then call Chrome DevTools Protocol’s Page.printToPDF. The handler should generate the PDF bytes first and only then write a successful PDF response.

How the conversion works

Think of the implementation as two cooperating parts: an HTTP layer and a rendering engine. Your handler validates the request and prepares HTML. A renderer loads that HTML, lays it out for print, and produces PDF bytes. The handler sets the response headers and writes those bytes to the client.

  1. Validate the request and build HTML using trusted templates and escaped data.
  2. Make that HTML available to the renderer, for example at a controlled application URL.
  3. Run the render with a deadline and handle any error before sending a success response.
  4. Set Content-Type: application/pdf and an inline or attachment Content-Disposition, then write the PDF bytes.
  5. Limit concurrent renders and document size for the selected engine. Browser processes can consume substantial resources beyond ordinary handler work.

The example below uses a controlled URL served by the same application. This keeps the example focused on PDF rendering without making the endpoint a general-purpose URL-fetch service.

Use Chromium and chromedp

chromedp drives a browser that speaks Chrome DevTools Protocol. Its official PDF example navigates to a page, calls Page.printToPDF, and receives PDF bytes. Install Chromium in the runtime environment and add the Go dependencies with go get github.com/chromedp/chromedp github.com/chromedp/cdproto/page. The package documents browser startup and attachment options in its project documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
#1 Best Overall
Sale
Epson EcoTank ET-2800 Wireless Color All-in-One Supertank Printer - Black
  • INNOVATIVE CARTRIDGE-FREE PRINTING — No more dealing with lots of tiny ink cartridges; With this wireless document and photo printer each ink bottle set is equivalent to about 90 individual cartridges²
  • LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; When you choose this combination printer, scanner and copier you can print up to 4,500 pages black/7,500 color³
  • COLOR PRINTING — Up to 2 years of ink in the box4 (and with every replacement ink set) for fewer out-of-ink frustrations
  • ZERO CARTRIDGE WASTE — By using an Epson EcoTank printer you can help reduce the amount of cartridge waste ending up in landfills
  • HOME PRINTER DESIGNED FOR RELIABILITY — The Epson EcoTank ET-2800 All-in-One Supertank Color Printer creates vivid, detailed prints and documents thanks to Micro Piezo Heat-Free Technology; Fire off 10 ISO pages per minute1 to easily finish large jobs

A minimal HTTP handler

This pattern assumes documentURL is a URL your application controls and serves. In a real service, obtain it from trusted application state rather than accepting an arbitrary URL from a client.

package main

import (
    "context"
    "log"
    "net/http"
    "time"

    "github.com/chromedp/chromedp"
    "github.com/chromedp/cdproto/page"
)

func pdfHandler(w http.ResponseWriter, r *http.Request) {
    if r.Method != http.MethodGet {
        http.Error(w, "method not allowed", http.StatusMethodNotAllowed)
        return
    }

    // Replace this with a URL for a page generated by your application.
    documentURL := "http://127.0.0.1:8080/report"

    // Each request has a bounded render time and is canceled if the client disconnects.
    ctx, cancel := context.WithTimeout(r.Context(), 30*time.Second)
    defer cancel()

    // chromedp uses headless mode by default. Ensure Chromium is installed
    // and available to the process in your deployment environment.
    browserCtx, browserCancel := chromedp.NewContext(ctx)
    defer browserCancel()

    var pdf []byte
    err := chromedp.Run(browserCtx,
        chromedp.Navigate(documentURL),
        chromedp.ActionFunc(func(ctx context.Context) error {
            var err error
            pdf, _, err = page.PrintToPDF().
                WithPrintBackground(true).
                Do(ctx)
            return err
        }),
    )
    if err != nil {
        http.Error(w, "could not render PDF", http.StatusBadGateway)
        return
    }

    w.Header().Set("Content-Type", "application/pdf")
    w.Header().Set("Content-Disposition", `attachment; filename="report.pdf"`)
    w.WriteHeader(http.StatusOK)
    if _, err := w.Write(pdf); err != nil {
        // The client may have disconnected; response headers are already sent.
        log.Printf("write PDF response: %v", err)
    }
}

func main() {
    http.HandleFunc("/report.pdf", pdfHandler)
    log.Fatal(http.ListenAndServe(":8080", nil))
}

The protocol call returns PDF bytes and an optional stream handle; this example uses the byte slice. The official example shows the same PrintToPDF().Do(ctx) flow. See the chromedp PDF example and the Page.printToPDF bindings.

Use application-generated HTML

For dynamic documents, render a Go html/template using trusted data and serve the resulting page on an internal, controlled route for Chromium to navigate to. Go’s HTML templates escape data in HTML contexts; avoid assembling markup through string concatenation. Keep the page route and PDF route distinct so the browser can load the complete document and its intended assets before printing.

If you prefer to pass markup directly rather than serve a page, choose and verify an input mechanism supported by your renderer. The sources cited here establish navigation to a page and PDF printing; they do not establish one universal safe approach for arbitrary HTML input.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #2
Sale
Epson EcoTank Photo ET-8550 Wireless Wide-Format All-in-One Tank Printer
  • CARTRIDGE-FREE PRINTING — Print lab-quality photos, graphics and creative projects; Get vibrant colors and sharp text with Epson's high-accuracy printhead and Claria ET Premium 6-color inks
  • INK BOTTLES — Save on photos1 and creative projects with affordable in-house printing; All-in-one printer allows you to print 4" x 6" photos for about 4 cents each vs. 40 cents with traditional ink cartridges1
  • LESS FREQUENT INK REPLACEMENT — Replacement ink bottles don't have to be changed nearly as often as ink cartridges¹; Printer, scanner and copier lets you print up to 6,200 color pages³
  • PRINT FOR LONGER — Up to 2 years of ink in the box² (and with every replacement ink set) for fewer out-of-ink frustrations with this wireless printer
  • ZERO CARTRIDGE WASTE — Epson EcoTank printer helps reduce the amount of cartridge waste ending up in landfills; Cartridge-free printer uses high-yield ink bottles; Each replacement ink bottle set is equivalent to about 100 individual ink cartridges⁴

Set print layout deliberately

Page.printToPDF exposes controls for page orientation, paper width and height, margins, background printing, and tagged-PDF generation. Use the protocol bindings for the available options and configure the fields your document requires rather than relying on defaults. For example, the handler enables background printing; without it, background colors and images may not appear as expected.

  • Paper size and orientation: choose dimensions that fit the document and whether pages should be portrait or landscape.
  • Margins: set margins to preserve readable space or align with a report’s layout.
  • Backgrounds: enable background printing when colors or background graphics carry meaning.
  • Tagged PDF: consider the tagged-PDF option when accessibility requirements apply, and validate the resulting document with your own accessibility checks.

Print CSS, fonts, page breaks, and external assets can change the result. Test the actual templates and representative content that the application will render; the API documentation describes controls, not a guarantee that every page will paginate as intended.

Choose a renderer that fits deployment

Approach What is established What to evaluate
Chromium with chromedp Go can drive a browser using Chrome DevTools Protocol; the official example uses Page.printToPDF and returns bytes. chromedp; PDF example. Whether Chromium is available in the deployment, required CSS and browser behavior, memory use, and concurrency limits.
wkhtmltopdf with a Go binding wkhtmltopdf is a headless Qt WebKit command-line tool. The Go binding requires wkhtmltox to be installed and documents a main-thread constraint. Project site; binding README. Legacy WebKit compatibility, native runtime packaging, license review, and how the main-thread constraint works with a concurrent HTTP server. Its advanced server example discusses the separate-goroutine challenge.
Pure-Go renderer This project presents basic CSS support without an external renderer requirement. Verify that the HTML and CSS you use are supported and compare output on representative documents before adopting it.
Hosted rendering API The GoPDF API reference describes accepting HTML or a URL and returning PDF output. Verify data-handling terms, service limits, pricing, latency, and program terms before relying on a hosted service.

These approaches are not equivalent drop-ins: they differ in rendering engine, runtime installation, and operational constraints. The cited material does not establish a benchmark or output-quality winner.

Protect the server and keep rendering reliable

Do not turn PDF generation into an unrestricted fetch proxy

If clients can submit URLs, the renderer becomes a server-side fetch capability. Restrict allowed destinations, block access to internal networks, and set time and resource limits. If clients can submit HTML, remember that it may load remote or local resources or execute scripts depending on renderer configuration. Apply an application-specific threat model; there is no single universal safe configuration established by the cited material.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
Rank #3
HP Smart Tank 5000 Wireless All-in-One Ink Tank Printer, Scanner, Copier with 2 Years of Ink Included, Best-for-Home, Cartridge-Free, Refillable and AI-Enabled. (5D1B6A)
  • SET IT UP ONCE AND PRINT WITH CONFIDENCE. No complicated maintenance. Just easy, reliable printing you can count on.
  • INK FOR YEARS. NOT MONTHS. Up to 2 years of ink included. Get thousands of pages of cartridge-free printing. More pages, less hassle
  • KEEPS PRINTING WELL AFTER COMPETITORS HAVE QUIT. No complex maintenance. Sharper text, richer colors.[2] Only with HP Smart Tank
  • PREMIUM SUPPORT - Strong technical expertise to solve issues faster
  • THE LAST PRINTER YOU'LL EVER NEED. Enjoy years of refillable, cartridge-free printing.

Bound time, input, and concurrency

Use request-scoped cancellation and an application-defined deadline, as in the example. Place a limit on simultaneous renders and on document size or complexity appropriate to your service. The exact limits depend on the renderer, deployment resources, and workload; no performance measurements are established here. Test cancellation behavior, resource loading, and concurrent jobs with the renderer and environment you actually deploy.

Plan for browser lifecycle

chromedp defaults to headless mode and documents how to start or attach to a browser. Its project documentation also notes that on Linux it force-kills started Chrome child processes when the Go program exits. Account for Chromium installation, startup, and lifecycle in deployment rather than assuming the handler alone provides a browser.

Troubleshoot common failures

  • Chromium cannot start: confirm the browser is installed and available in the runtime environment; inspect the chromedp startup or attachment configuration.
  • The render times out: inspect page load behavior and resource requests, then set an appropriate application deadline and limit expensive or untrusted content. Do not respond with PDF bytes when rendering failed.
  • The PDF is blank or incomplete: confirm the controlled page is reachable by the browser process and that required content and assets finish loading before printing. Verify loading behavior for the selected renderer.
  • Styles or backgrounds are missing: verify that the document’s assets load and enable background printing when needed; inspect print-specific CSS and pagination.
  • Response is not a valid PDF: ensure the handler writes the byte slice returned by the PDF operation, sets Content-Type before writing, and does not emit other response content first.
  • Concurrent jobs fail or exhaust resources: reduce simultaneous renders and investigate browser process and memory usage in the deployment. The appropriate limit is workload-specific.
  • wkhtmltopdf behaves poorly in an HTTP handler: check the binding’s main-thread constraint and its advanced server example before using it in a concurrent server.
Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Or skip the browser setup

If the HTML is available at a URL and a screenshot or rendered PDF from that page is what you need, ScreenshotNeo offers a website screenshot API. Its API is not a drop-in renderer for arbitrary local Go template bytes: the example below captures a URL, so publish or otherwise make the page reachable to the service first. See the ScreenshotNeo documentation for API options.

curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp

ScreenshotNeo accepts cookie and consent banners before capture and removes 60+ known consent platforms, newsletter popups, and chat widgets; each cleanup step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers identify the page verdict and billing status. Its MCP server provides take_screenshot, get_page_info, and capture_pdf tools for AI agents. The Free plan includes 1,000 shots per month with no card; paid plans start at $5 for 3,000 shots.

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

Sign up free for 1,000 screenshots a month with no card.

Rank #4
NDYIN Portable Printers Wireless for Travel, N80 Bluetooth Thermal Printer
  • Wireless Bluetooth Printer: Portable thermal printer compatible with iPhone, Android phones, iPad and tablet computers via Bluetooth. For smartphones, please download the "Nada Print" App. You can also connect to laptops and computers for printing using a USB-C cable. (Note: Laptops and computers can only be connected via USB and require the installation of a driver first. Bluetooth connection is not supported.)
  • No-ink printing: Only supports US Letter and A4 size thermal paper.(Doesn't support regular paper) The no-ink portable thermal printer uses direct thermal technology, requiring no ink, toner or ribbons, making it environmentally friendly, cost-effective and time-saving. The thermal printer package comes with a roll of US Letter thermal printing paper. Note: When installing the paper, remember to switch the paper size switch on APP
  • Clear Print: NDYIN N80 portable thermal printer adopts high-definition printing technology, with a 203DPI resolution to provide you with clear printing results. This mobile printer is compatible with roll paper, folded paper and tattoo transfer paper, supporting printing from your mobile phone PDF, Word, pictures and web pages anytime and anywhere. It is recommended to use our NDYIN thermal paper to achieve good printing quality
  • Portable wireless printer for travel: The thermal printer is equipped with a built-in 1500mAh rechargeable battery, which can print 160 sheets of 8.5" x 11" thermal paper after being fully charged. It weighs only 1.5 pounds and is compact in size. This ink-free portable printer can be easily carried in a backpack or briefcase! It is perfect for business travel, cars, small offices, construction sites, schools and homes. You can print documents, contracts, invoices and boarding passes anytime and anywhere
  • The N80 thermal printer has a wide range of uses. The package includes the N80 printer, a roll of US Letter paper(7m/roll), a user manual, a guide card, a type-C soft cable and a type C adapter. Note: The charging adapter is not included. Special thermal paper is required for use; ordinary paper cannot be used. This ink-free portable thermal printer is suitable for various scenarios such as home, school, travel, office, and outdoor, meeting the printing needs of different groups of people. This tattoo template printer is also compatible with tattoo transfer paper, making it an ideal choice for tattoo art

Frequently asked questions

Does Go’s net/http package convert HTML to PDF by itself?

No. It receives requests and writes responses. Pair it with a renderer such as Chromium driven by chromedp.

Can the endpoint return a PDF in the browser instead of downloading it?

Yes. Set Content-Disposition to an inline disposition instead of the attachment disposition shown in the example; browser behavior can vary.

Does the example establish a specific Go or Chromium version?

No. The cited documentation establishes the API pattern, not a tested package-version matrix. Pin and validate the versions used by your application and deployment.

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

Quick Recap

Bestseller No. 3
HP Smart Tank 5000 Wireless All-in-One Ink Tank Printer, Scanner, Copier with 2 Years of Ink Included, Best-for-Home, Cartridge-Free, Refillable and AI-Enabled. (5D1B6A)
HP Smart Tank 5000 Wireless All-in-One Ink Tank Printer, Scanner, Copier with 2 Years of Ink Included, Best-for-Home, Cartridge-Free, Refillable and AI-Enabled. (5D1B6A)
PREMIUM SUPPORT - Strong technical expertise to solve issues faster; THE LAST PRINTER YOU'LL EVER NEED. Enjoy years of refillable, cartridge-free printing.
$194.03

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.