Driver FixRecommendedSound, Wi-Fi or graphics acting up? Check drivers firstFind missing or outdated drivers fast.Check DriversOctober DealsAmazon USOctober deal check: compare before you payAmazon US: current deals, useful picks and tech finds.Check DealsWindows FixRecommendedWindows errors stealing your time? Find the fix fastScan stability, cleanup and performance issues.Fix Now×
Skip to content
Go

How to Pass Data to a wkhtmltopdf Footer in Go

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

To put application data in a wkhtmltopdf footer from Go, you must explicitly pass it to the footer document. For built-in values such as the current page and total page count, use wkhtmltopdf’s footer substitutions. For your own values, configure the HTML footer and use a supported replacement mechanism—such as the binary’s --replace option—or supply the data to a footer endpoint as query parameters. A Go variable does not become a footer variable automatically.

Choose the right way to supply the value

There are two different kinds of footer data, and choosing between them first avoids a common implementation mistake:

  • Document metadata and pagination: use wkhtmltopdf’s built-in substitutions, such as [page], [topage], [title], and [date].
  • Application-specific values: explicitly pass the value through a replacement mechanism supported by your binary or Go wrapper, or make it available to the HTML footer through its URL.

The wkhtmltopdf manual documents --footer-html <url> and says that arguments are sent to header and footer HTML documents in GET fashion. Its example reads the footer document’s query string and uses matching element classes to display values. The manual’s usage page describes wkhtmltopdf 0.12.6 with patched Qt; behavior can differ in other binaries, forks, or wrapper releases. See the wkhtmltopdf usage documentation.

If the value is simply a page number or document title, a built-in substitution is usually the simplest route. If it is an invoice number, customer name, or other value created by your Go application, choose a custom-data route and verify that your exact binary or wrapper supports it.

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

Use built-in footer substitutions for page and document fields

For a text footer, wkhtmltopdf provides fields including [page], [frompage], [topage], [webpage], [section], [subsection], [date], [isodate], [time], [title], [doctitle], [sitepage], and [sitepages]. For example, a footer text option can contain Page [page] of [topage]. These are wkhtmltopdf substitutions, not arbitrary Go template variables.

When using an HTML footer, its document can include elements for the standard values. The manual’s example uses classes corresponding to the values and footer-side JavaScript to read the query string and populate those elements. A minimal markup pattern is:

<div>Page <span class="page"></span> of <span class="topage"></span></div>

Use the documented footer example as the reference for how your particular build supplies the values to the HTML document. Do not assume that the literal text [page] will be substituted in every location in your own JavaScript or HTML; the substitution mechanism and context matter.

Pass application-specific data with the wkhtmltopdf binary

When you invoke wkhtmltopdf directly, the general pattern is to select a footer document with --footer-html and pass custom replacement data with the binary’s supported options. The CLI exposes --replace for replacing a named value in header and footer HTML. A representative invocation is:

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
wkhtmltopdf 
  --footer-html /absolute/path/footer.html 
  --replace invoice_number INV-2048 
  https://example.com/invoice/2048 
  invoice.pdf

Check the usage help for the exact syntax and behavior of the wkhtmltopdf binary installed in your deployment environment. The Go wrapper’s source also exposes a footer HTML option and a repeatable Replace map option, but the source alone does not establish the encoding, escaping, or custom-placeholder details for every release. Review the Go wrapper source and the release you use.

A footer HTML file can contain a matching target element, for example:

<div>Invoice: <span class="invoice_number"></span></div>
<script>
(function () {
  var params = new URLSearchParams(window.location.search);
  var value = params.get('invoice_number');
  if (value !== null) {
    document.querySelector('.invoice_number').textContent = value;
  }
})();
</script>

The manual documents GET-style arguments and an example that associates query keys with elements by class. The example above illustrates safe text insertion with textContent; confirm the exact query keys and replacement behavior against your build. Do not put untrusted values into innerHTML: a customer name or other user-controlled field should be treated as text, not executable markup.

Invoke wkhtmltopdf from Go without shell interpolation

One portable Go-side pattern is to assemble the executable’s arguments as a slice and call exec.Command. This keeps values out of a shell command string. The sample assumes the installed binary accepts the shown CLI options; verify those options against the version deployed. It also assumes that the input page can be loaded by the binary and that the footer file path is accessible to it.

Free tools Windows power users keep installed

One-click scans. No signup required.

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

import (
	"context"
	"fmt"
	"os/exec"
	"time"
)

func renderPDF(ctx context.Context, inputURL, outputPath, footerPath, invoiceNumber string) error {
	args := []string{
		"--footer-html", footerPath,
		"--replace", "invoice_number", invoiceNumber,
		inputURL,
		outputPath,
	}

	cmd := exec.CommandContext(ctx, "wkhtmltopdf", args...)
	output, err := cmd.CombinedOutput()
	if err != nil {
		return fmt.Errorf("wkhtmltopdf failed: %w: %s", err, output)
	}
	return nil
}

func main() {
	ctx, cancel := context.WithTimeout(context.Background(), 2*time.Minute)
	defer cancel()

	err := renderPDF(ctx,
		"https://example.com/invoice/2048",
		"invoice.pdf",
		"/absolute/path/footer.html",
		"INV-2048",
	)
	if err != nil {
		panic(err)
	}
}

Keep arguments as separate slice entries; do not concatenate a URL, invoice number, or other input into a shell command and pass it through sh -c. The example reports the converter’s combined output when execution fails, which can help diagnose a missing resource or invalid option. A production service should also choose a timeout appropriate to its documents and impose its own input and output limits.

If your Go wrapper provides FooterHTML and Replace, use the names and types documented for the specific release you have selected. For example, the wrapper source describes a footer HTML option and a repeatable replacement map. Do not assume that an illustrative method call is valid for every wrapper version: compile against the pinned dependency and verify how it serializes replacement values.

Supply values through a footer URL when that fits your deployment

An alternative is to make the footer an endpoint that receives the application value in its query string. Build the URL with Go’s URL tools rather than concatenating raw values:

u, err := url.Parse("https://app.example.com/pdf-footer")
if err != nil {
	return err
}
q := u.Query()
q.Set("invoice_number", invoiceNumber)
u.RawQuery = q.Encode()
footerURL := u.String()

Pass footerURL as the value of --footer-html, or through the equivalent wrapper option. The endpoint can read the query value and render it into the footer page. This route makes the data flow explicit, but it requires the converter to reach the endpoint. Treat a query string as a transport mechanism, not a safe place for secrets: URLs may be recorded in logs. If a value is sensitive, choose a design that does not expose it in a URL and control access to the footer resource.

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

A local footer file and a served footer URL have different operational requirements. The binary must be able to read a local file in its runtime environment; a URL requires network access and whatever authentication or routing that endpoint needs. The reviewed documentation does not establish one universal recipe for local-file access across builds and configurations. Test the chosen resource type in the same container, host, or service account that performs production conversion.

Independent reader supportYour contribution helps us test, update, and keep practical guides available for everyone.Support on Ko-Fi

Leave printable space for the footer

A correct value can still appear missing if the footer is outside the page’s printable area or overlaps document content. wkhtmltopdf exposes page-margin settings and footer spacing. Increase the bottom margin to reserve room for the footer, then adjust footer spacing as needed. The libwkhtmltox settings documentation warns that header or footer spacing that is too large can put content outside the page. It also documents page offset behavior for numbering in headers, footers, and the table of contents. See the page settings documentation.

Do not treat footer spacing as a substitute for a suitable page margin: the footer needs both a position and enough page area to fit. Render representative documents with the actual paper size, margins, and footer dimensions used in production.

Troubleshoot missing, malformed, or misplaced values

  • The footer renders, but the custom value is empty. Confirm that the application actually passes the value, that the replacement name matches the footer’s expected key, and that your binary or wrapper release supports the mechanism you chose. A Go variable by itself is not visible to footer JavaScript.
  • The value is present in a footer URL but not displayed. Inspect the actual URL and query key received by the footer, then confirm that the markup selector matches the element and that the footer script runs. Use URL encoding when building query strings; do not assume raw spaces, ampersands, or non-ASCII text will survive concatenation.
  • The value is truncated or interpreted unexpectedly. Avoid shell-string construction and pass each argument separately. Check how the installed binary or wrapper handles replacement values and special characters; the cited wrapper source does not establish universal escaping behavior.
  • A local footer works on a developer machine but fails in deployment. Check that the converter process can see the file at the specified path and that the selected build’s local-resource configuration permits access. A path on the Go host may not exist inside a container or worker.
  • The footer is clipped or overlaps the body. Reserve additional page margin for it and review footer spacing, paper size, and content height. Oversized spacing can place the footer beyond the page.
  • Page numbers are wrong or start at an unexpected number. Distinguish built-in substitutions such as [page] and [topage] from application data, and review page offset settings for the deployed command.
  • The footer works with one binary but not another. Record the wkhtmltopdf version and wrapper release used in development and production, and check that build’s documentation. The main manual describes 0.12.6 with patched Qt; that does not prove identical behavior for other binaries or forks.

Or skip the browser setup

ScreenshotNeo is a website screenshot API, not a wkhtmltopdf footer-data mechanism: it will not pass application variables into a PDF footer. If your task is instead to capture a website as an image or PDF, one GET request can return the capture. See the ScreenshotNeo API and MCP server and its documentation.

Special offer. See more information about Outbyte and uninstall instructions. Please review EULA and Privacy policy.
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 or consent banners and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; those steps can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and the response includes X-Page-Verdict and X-Billed headers. Its MCP server provides take_screenshot, get_page_info, and capture_pdf for AI agents and MCP clients. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots. Sign up free for 1,000 screenshots a month with no card.

Frequently Asked Questions

Can Go variables be referenced directly in a wkhtmltopdf footer?

No. Your Go code must pass each application-specific value through a supported replacement option or make it available to the footer document.

Which built-in fields are useful for pagination?

The manual lists [page], [frompage], [topage], [sitepage], and [sitepages], among other document metadata substitutions.

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.

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

Leave a Reply

Your email address will not be published. Required fields are marked *

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

Read next

Recommended PC Tool
Recommended PC Tool
PC Slower Than It Used to Be?Free scan - under a minute
Outdated Drivers Are Slowing You DownFree scan - exact matches

Two free Windows tools

One Free Minute Could Fix That PC

Before you go - each of these free tools takes about a minute and tackles what quietly slows a Windows PC down.

Special offer. View Outbyte info, uninstall instructions, EULA, and Privacy Policy.