Internal callback server
The app/pdfrender/server package runs a second HTTP server, bound to 127.0.0.1 on a random port, that the browser talks to while rendering. It never faces the outside network.
Why it exists
The browser needs a URL to navigate to. Rather than write HTML to disk, the renderer stores the Document in an in-memory store keyed by a random document ID and hands the browser a URL on this internal server. The server then streams the document’s HTML and its assets to the browser.
Routes
| Route | Purpose |
|---|---|
GET /templates/:name/:document_id | Returns the rendered body HTML the browser loads. |
GET /templates/:name/:document_id/callback | The page calls this to fire the callback lifecycle event. |
GET /templates/:name/assets/* | Serves the template’s assets/ to the browser. |
The callback flow
When a template uses waitLifecycleEvent: callback, the renderer creates a callback channel stored alongside the document. The rendered page fetches the …/callback URL when ready; the handler signals the channel; the renderer unblocks and prints. See Lifecycle events.
Trace propagation
The internal server reconstructs the parent span from trace context passed as query parameters (or the Referer header), so browser-side requests join the same OpenTelemetry trace as the originating render.
Assets resolution
GetAsset looks up the template via the StoreConsumer (the LazyStore) and serves files from its assets provider. Path traversal outside a template’s assets/ directory is prevented.