Skip to content

docs: document Gotenberg PDF generation - #20

Merged
gdarko merged 1 commit into
masterfrom
feat/gotenberg-pdf-docs
Jul 29, 2026
Merged

docs: document Gotenberg PDF generation#20
gdarko merged 1 commit into
masterfrom
feat/gotenberg-pdf-docs

Conversation

@gdarko

@gdarko gdarko commented Jul 29, 2026

Copy link
Copy Markdown
Contributor

Changes

The site had no Gotenberg coverage at all — grep -ri gotenberg across the repo returned nothing — despite it being a supported PDF driver. The only way to learn the setup was to read config/pdf.php in the app.

Adds guide/pdf-generation.md and a sidebar entry next to Custom Templates.

The page covers:

  • When to switch from dompdf. Framed around the two things that actually justify running another service: dompdf uses the first font in the chain for every character rather than falling back per glyph, so mixed-script documents render boxes; and its CSS support predates most modern layout features, which matters if you maintain custom templates.
  • A compose example, with the Gotenberg port deliberately left unpublished — it has no authentication of its own.
  • The settings, with defaults, and a note that the database value wins over the environment.
  • Private networks and the SSRF guard, which is most of the page.
  • Troubleshooting, for the errors people actually hit.

On the private-network section

This is the part worth reviewing. Gotenberg normally runs as a sidecar on a private network, which InvoiceShelf blocks by default, so the standard setup hits a wall on first save with a message that explains the rule but not the remedy.

The page explains why the guard exists — InvoiceShelf returns the upstream response body to the browser as the PDF, so an unrestricted host is a way to read internal services — and then why GOTENBERG_ALLOWED_PRIVATE_HOST names a single host instead of being an on/off switch, and why it is environment-only rather than a toggle in the admin UI. That reasoning isn't discoverable from the error message and is the thing people will search for.

It also documents the behaviour that a hostname which does not resolve saves cleanly and only fails at render time, since that turns a typo into a confusing delayed failure.

Test plan

  • yarn build passes; guide/pdf-generation.html is emitted.
  • Sidebar entry renders under Documentation.
  • The one internal link (/guide/custom-templates.md) resolves — VitePress fails the build on dead links, so the passing build covers this too.

Notes

Written against the behaviour in InvoiceShelf 3.x as of InvoiceShelf/InvoiceShelf#691 and #699, which introduced GOTENBERG_ALLOWED_PRIVATE_HOST and made the dev compose stacks configure it automatically.

The site had no Gotenberg coverage at all, despite it being a supported
PDF driver — so the only way to learn the setup was to read config/pdf.php.

Covers when to switch from dompdf (mixed-script documents, modern CSS in
custom templates), a compose example, the settings and their defaults,
and troubleshooting for the errors people actually hit.

Most of the page is the private-network section. Gotenberg normally runs
as a sidecar, InvoiceShelf blocks private hosts because it returns the
upstream response as the PDF, and GOTENBERG_ALLOWED_PRIVATE_HOST names
one host rather than switching the guard off. That trips people up on
first setup and the reasoning is not obvious from the error message.
@gdarko
gdarko merged commit 64b887f into master Jul 29, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant