HTML to PDF in Go
Overview
Convert web pages and HTML documents to PDF with the PDFCrowd Go client. The client handles communication with the API, while conversions run on PDFCrowd's servers.
Installation
Add the Go client to your module with go get, or see
other installation options.
go get github.com/pdfcrowd/pdfcrowd-go
Quick Start
You can run the examples below with the displayed API credentials. Update the input URLs and filenames as needed.
Convert a URL
Convert a web page to PDF and save it locally as example.pdf:
package main import ( "log" "github.com/pdfcrowd/pdfcrowd-go" ) func main() { client := pdfcrowd.NewHtmlToPdfClient("demo", "demo") client.SetContentViewportWidth("balanced") err := client.ConvertUrlToFile("https://example.com/", "example.pdf") checkError(err) } func checkError(err error) { if err != nil { log.Fatal(err) } }
The balanced viewport setting fits the HTML viewport to the print area.
Conversion methods return an error if the input or settings are invalid, or if the conversion fails. See Handle Errors.
Convert an HTML File
Upload document.html and save the converted PDF locally as
document.pdf:
package main import ( "log" "github.com/pdfcrowd/pdfcrowd-go" ) func main() { client := pdfcrowd.NewHtmlToPdfClient("demo", "demo") client.SetContentViewportWidth("balanced") err := client.ConvertFileToFile("document.html", "document.pdf") checkError(err) } func checkError(err error) { if err != nil { log.Fatal(err) } }
For HTML that references local images or stylesheets, see Include Local Assets. To pass an HTML string, see Send HTML Content.
Configure a Conversion
Authentication
Pass your PDFCrowd username and API key to
NewHtmlToPdfClient.
Find your credentials on the API Keys page.
To load a protected source website, configure its website credentials, cookies, or HTTP headers separately.
Choose an Input
| Input | Method |
|---|---|
| Web page URL | ConvertUrlToFile() |
| HTML string | ConvertStringToFile() |
| Local HTML file or archive | ConvertFileToFile() |
URLs must be reachable from PDFCrowd's servers. For a page on
localhost, send its HTML content or upload a file.
Referenced assets must also be reachable from PDFCrowd's servers or included
in an archive.
Send HTML Content
Convert an HTML string to PDF and save it as report.pdf:
package main import ( "log" "github.com/pdfcrowd/pdfcrowd-go" ) func main() { client := pdfcrowd.NewHtmlToPdfClient("demo", "demo") html := ` <!doctype html> <html><body><h1>Monthly report</h1></body></html>` client.SetContentViewportWidth("balanced") err := client.ConvertStringToFile(html, "report.pdf") checkError(err) } func checkError(err error) { if err != nil { log.Fatal(err) } }
Replace html with the output of your template renderer.
For relative resource URLs, add a
<base href="https://your-site.example/"> element to the HTML head,
or use absolute URLs.
Replace https://your-site.example/ with your website's public URL.
The <base> element tells PDFCrowd where to resolve relative URLs.
For example, /static/style.css becomes
https://your-site.example/static/style.css.
PDFCrowd can also combine an HTML template with structured data; see HTML templates.
Include Local Assets
Package the HTML and its local images, CSS, and JavaScript in a
.zip, .tar.gz, or .tar.bz2 archive.
Preserve the relative paths used by the HTML.
Convert the HTML document inside document.zip and save the PDF
as output.pdf:
package main import ( "log" "github.com/pdfcrowd/pdfcrowd-go" ) func main() { client := pdfcrowd.NewHtmlToPdfClient("demo", "demo") client.SetContentViewportWidth("balanced") err := client.ConvertFileToFile("document.zip", "output.pdf") checkError(err) } func checkError(err error) { if err != nil { log.Fatal(err) } }
The API automatically converts the first HTML file it finds in the archive.
If the archive contains multiple HTML files, use
SetZipMainFilename() to choose which one to convert.
Add Conversion Settings
Set conversion options on the client before calling a conversion method.
For example, client.SetPageSize("A4") selects A4 paper.
Common settings are listed below. See the method reference for all available options, browse Go examples, or try settings in the API Playground.
| Purpose | Methods |
|---|---|
| Page size and margins | SetPageSize(), SetPageMargins(), SetNoMargins(), SetOrientation() |
| Headers and footers | SetHeaderHtml(), SetFooterHtml(), SetHeaderHeight(), SetFooterHeight() |
| Layout and scaling | SetContentViewportWidth(), SetScaleFactor() |
| Print styles and custom CSS | SetUsePrintMedia(), SetCustomCss() |
| JavaScript and readiness | SetCustomJavascript(), SetWaitForElement(), SetJavascriptDelay() |
| Convert a specific element | SetElementToConvert() |
Handle the Result
Choose an Output
The methods below use URL input; HTML strings and files have corresponding methods.
| Output | Method |
|---|---|
| Local file | ConvertUrlToFile() |
| Byte slice | ConvertUrl() |
io.Writer | ConvertUrlToStream() |
File-output methods overwrite an existing destination file.
This example converts a web page, receives the result as a
[]byte and saves it as example.pdf:
package main import ( "log" "os" "github.com/pdfcrowd/pdfcrowd-go" ) func main() { client := pdfcrowd.NewHtmlToPdfClient("demo", "demo") result, err := client.ConvertUrl("https://example.com/") checkError(err) checkError(os.WriteFile("example.pdf", result, 0644)) } func checkError(err error) { if err != nil { log.Fatal(err) } }
When serving the PDF from a web application, use Content-Type: application/pdf.
Handle Errors
Conversion methods return an error. API and validation errors have the
type pdfcrowd.Error; local file and
connection failures can return other error types.
This example converts a web page, logs any error,
and uses errors.As to read the HTTP status and reason code when available:
package main import ( "errors" "log" "github.com/pdfcrowd/pdfcrowd-go" ) func main() { client := pdfcrowd.NewHtmlToPdfClient("demo", "demo") err := client.ConvertUrlToFile( "https://example.com/", "example.pdf", ) checkError(err) } func checkError(err error) { if err != nil { var apiError pdfcrowd.Error if errors.As(err, &apiError) { log.Printf("Status: %d; reason: %d", apiError.GetStatusCode(), apiError.GetReasonCode()) } log.Fatal(err) } }
pdfcrowd.Error provides these methods:
| Method | Returns |
|---|---|
GetStatusCode() | The HTTP status code, when available. |
GetReasonCode() | The reason code identifying the specific error, or -1 if unavailable. |
GetMessage() | The error message. |
GetDocumentationLink() | A link to relevant documentation, when available. |
Error() returns the complete error message, including available status and reason codes.
Common Status Codes
| Status | What it means | What to do |
|---|---|---|
400 | Invalid input, settings, or conversion failure | Read the reason code and correct the input or settings. |
401 | Missing credentials or an inactive license | Check your username, API key, and license status. |
403 | Suspended service or no credits remaining | Check your account and available credits. |
413 | Upload exceeds the 300 MB limit | Reduce the upload size. |
429 | Request rate limit reached | Wait and reduce the rate of new requests. |
430 | Concurrent request limit reached | Allow active requests to finish before starting more. |
503 | Temporary network issue | Check your retry policy before submitting another request. |
See all status and reason codes for specific explanations and Limits and Retries for retry behavior.
Read Conversion Information
This information is available after a conversion and describes the client's last conversion.
| Method | Use |
|---|---|
GetJobId() | Identify the conversion in logs and support requests. |
GetDebugLogUrl() | The URL of the conversion debug log when logging is enabled. |
GetPageCount() | Read the number of pages in the PDF. |
GetOutputSize() | Read the PDF size in bytes. |
GetConsumedCreditCount() | Read the credits consumed by the conversion. |
GetRemainingCreditCount() | Read the remaining credit count reported with the conversion. |
Limits and Retries
Request rate and concurrency limits depend on your license. Control how quickly
your application submits conversions and how many it runs at once. A
429 response concerns request rate; a 430 response
concerns requests already in progress. The maximum upload size is 300 MB.
The Go client automatically retries a request once when it receives HTTP
502 or 503. Use
SetRetryCount()
to change that count, or set it to 0 to disable automatic retries.
Account for these retries when adding an application-level retry policy.
PDFCrowd stops a conversion that exceeds 60 seconds of processing time.
Reason code 323 identifies this HTML conversion timeout.
Check for slow resource downloads or long-running JavaScript. Allowing your
application to wait longer does not extend the server's processing limit.
Troubleshooting
Inspect a Conversion
This example converts a web page with debug logging enabled and logs the debug log URL when available. Use the input and settings from the conversion you are investigating.
package main import ( "log" "github.com/pdfcrowd/pdfcrowd-go" ) func main() { client := pdfcrowd.NewHtmlToPdfClient("demo", "demo") client.SetDebugLog(true) err := client.ConvertUrlToFile( "https://example.com/", "example.pdf", ) if debugLogURL := client.GetDebugLogUrl(); debugLogURL != "" { log.Printf("Debug log: %s", debugLogURL) } checkError(err) } func checkError(err error) { if err != nil { log.Fatal(err) } }
The debug log includes resource-loading details, timeouts, and browser console messages. You can also find logs in your conversion history. A local or connection failure may occur before a conversion log is available.
Common Problems
| Problem | Check |
|---|---|
| Images or styles are missing | Check resource URLs and authentication. See Include Local Assets for local resources. |
| A login page appears in the output | Check the source website's authentication. |
| Dynamic content is missing | Use SetWaitForElement() or SetJavascriptDelay(), and inspect the debug log. |
| The layout has the wrong width | Adjust SetContentViewportWidth(). |
| The output needs print-specific styling | Enable SetUsePrintMedia() if the page supplies print styles, or add SetCustomCss(). |
| The application times out before receiving a result | Check client and application timeouts. Allow for uploading the input, conversion, and downloading the result. |
For help, contact support and include any available diagnostics, the client version, and enough detail to reproduce the problem.