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.