Images and custom fonts in API-rendered PDFs
pdfrender never fetches external URLs — embed images, fonts and CSS as data: URIs instead. Why that design is safer, and how to inline assets.
Last updated
| External http(s) resources | never fetched — a document referencing one is rejected with 400 listing the URLs |
|---|---|
| Supported instead | data: URIs for images, fonts and stylesheets |
pdfrender deliberately never fetches external resources: a public
HTML renderer that follows arbitrary URLs is a server-side request forgery
(SSRF) vector and makes renders non-deterministic (a slow or changed remote
image changes your PDF). Instead, everything ships inside the document as
data: URIs:
<img src="data:image/png;base64,iVBORw0KGgoAAA…" alt="logo">
<style>
@font-face {
font-family: "Inter";
src: url("data:font/woff2;base64,d09GMgABAAA…") format("woff2");
}
body { font-family: "Inter", sans-serif; }
</style>
Encoding an asset is one line:
base64 -w0 logo.png # then prefix with data:image/png;base64,
import base64
uri = "data:image/png;base64," + base64.b64encode(open("logo.png", "rb").read()).decode()
Budget
Inlined assets count toward the 2 MiB request cap — base64 adds
about 33 % overhead, so keep images sized for print (a 150-300 dpi logo, not
a camera original). If a document references an external URL anyway, the API
returns 400 external_resource_blocked with the offending URLs listed, so
the fix is mechanical.
Try it free
Try it free — 100 renders a month, no card — or check your inlined document in the free browser tool.
FAQ
- Why does pdfrender reject external image and font URLs?
- Because it never fetches external resources by design. A renderer that follows arbitrary URLs from user-supplied HTML is a server-side request forgery surface; refusing to fetch removes it entirely. The 400 response lists the offending URLs.
- How do I embed a custom font in a generated PDF?
- Base64-encode the font file and reference it from an @font-face src as a data: URI. The same applies to images and external stylesheets.
- Does inlining assets count against the size limit?
- Yes. Base64 encoding adds roughly a third to a file's size, and the 2 MiB REST limit applies to the whole payload — so subset fonts and compress images before encoding.