Accrue renders invoice PDFs through a behaviour boundary so hosts can replace the default ChromicPDF path when their deployment shape requires something else. Common examples are a sidecar renderer, an internal document service, or an environment that cannot run Chromium locally.
The public contract is the Accrue.PDF behaviour. Keep adapters focused on
HTML-in, PDF-binary-out, and avoid reaching into invoice or email internals.
Behaviour contract
Define a module that implements the behaviour:
defmodule MyApp.PDF.Adapter do
@behaviour Accrue.PDF
@impl true
def render(html, opts) when is_binary(html) and is_list(opts) do
_ = {html, opts}
{:ok, "%PDF-CUSTOM"}
end
endThe required marker is:
@behaviour Accrue.PDFKeep secrets, endpoints, and credentials in host-app runtime config or env
vars. Guide snippets should use placeholders such as "https://pdf.example.test"
or "PDF_SERVICE_TOKEN" rather than real values.
Runtime configuration
Wire the adapter in config:
config :accrue, :pdf_adapter, MyApp.PDF.AdapterThat keeps calls on the stable facade:
Accrue.PDF.render("<html><body>invoice preview</body></html>", size: :a4)See guides/pdf.md for the built-in adapter behavior, paper-size options, and
the shared template path used by invoice email and PDF rendering.
Null adapter fallback
If the deployment target cannot render PDFs at all, point Accrue at
Accrue.PDF.Null:
config :accrue, :pdf_adapter, Accrue.PDF.NullAccrue.PDF.Null satisfies the same behaviour but returns a typed disabled-PDF
error instead of raising. That lets invoice mail flows degrade to hosted links
without pretending a PDF binary exists.
Dry-run verification
Verify the adapter in the host app before shipping:
- Configure the adapter in
config/runtime.exsor an environment-specific config file with placeholder endpoint values. - Render a sample invoice HTML through
Accrue.PDF.render/2. - Confirm the adapter returns
{:ok, pdf_binary}for the enabled path, or the documented disabled error for the null path. - Run the docs gate so guide references stay valid:
mix docs --warnings-as-errors
That last step matters because a custom adapter guide is only useful if the release docs still build cleanly in the consuming app and in Accrue itself.