Why Html2Pdf.app PDFs Miss Images or Web Fonts and How to Fix It
Missing images or fonts in an Html2Pdf.app PDF usually point to unreachable assets, loading delays, CSS media rules, or header and footer restrictions.
If images or web fonts are missing from an Html2Pdf.app PDF, first check that the source page and every required image, stylesheet, and font file are publicly reachable by the rendering service. Then check when those resources load, whether the page needs screen or print CSS, and whether the missing image is in a header or footer template. Html2Pdf.app renders with headless Chromium, so resource access, CSS media mode, and JavaScript timing can affect the output.
1. Check that the page and its assets are public
A page can open in your browser while still depending on resources that the PDF renderer cannot fetch. For example, an image, CSS file, or font might require a login, be available only on an internal network, or have a URL that expires. The Html2Pdf.app troubleshooting guidance recommends confirming that the source URL and required CSS, fonts, and images are reachable by the renderer. See its cURL troubleshooting guide.
- Open the source URL in a private browser session or another environment without your logged-in cookies.
- Identify the exact image, stylesheet, and font URLs the page uses.
- Check each URL independently. It should return the intended asset without a login, session cookie, or other browser-only state.
- If you submit raw HTML rather than a page URL, check that every external resource referenced by that HTML is public too.
For a practical check, copy an asset URL from the browser’s network panel and request it without authentication. A successful response in your logged-in browser does not prove that the renderer can access it.
2. Check web font declarations and access
Html2Pdf.app documents Google Fonts and self-hosted fonts through CSS @font-face. The stylesheet containing the declaration and the font file itself must be reachable without authentication. The official documentation covers fonts and conversion parameters.
/* Example for a self-hosted font. Replace the URL with a public font file. */
@font-face {
font-family: "Report Sans";
src: url("https://example.com/fonts/report-sans.woff2") format("woff2");
font-style: normal;
font-weight: 400;
}
body {
font-family: "Report Sans", sans-serif;
}
This is a CSS example, not an Html2Pdf.app request body. Serve the stylesheet and font file at URLs the rendering service can fetch. Check that the declared family, weight, and style match the rules used by the page. If the font URL redirects to an authenticated page or returns an error, fix access or use a publicly served asset.
3. Allow time for JavaScript and asynchronous resources
If the page inserts images or starts loading resources after JavaScript runs, the PDF may be generated before those resources are ready. Html2Pdf.app provides waitFor, a delay in seconds before PDF generation, documented from 0 to 10 seconds. Try a small delay and compare the result. A delay can help with late loading; it cannot make a private or inaccessible file available.
The examples below show a complete cURL request and Python and Node.js equivalents using the documented url, apiKey, and waitFor parameters. Set HTML2PDF_API_KEY in your shell to your Html2Pdf.app API key, and replace the example page URL with yours. Consult the official documentation for the account-specific endpoint and request options.
export HTML2PDF_API_KEY="YOUR_API_KEY"
curl -X POST "https://api.html2pdf.app/v1" \
-H "Content-Type: application/json" \
-d '{"url":"https://example.com/report","apiKey":"'"$HTML2PDF_API_KEY"'","waitFor":3}' \
-o report.pdf
import os
import requests
api_key = os.environ["HTML2PDF_API_KEY"]
response = requests.post(
"https://api.html2pdf.app/v1",
json={
"url": "https://example.com/report",
"apiKey": api_key,
"waitFor": 3,
},
timeout=90,
)
response.raise_for_status()
with open("report.pdf", "wb") as pdf:
pdf.write(response.content)
const apiKey = process.env.HTML2PDF_API_KEY;
if (!apiKey) throw new Error("Set HTML2PDF_API_KEY first");
const response = await fetch("https://api.html2pdf.app/v1", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
url: "https://example.com/report",
apiKey,
waitFor: 3,
}),
});
if (!response.ok) {
throw new Error(`PDF request failed: ${response.status} ${await response.text()}`);
}
await Bun.write("report.pdf", response);
Use the endpoint and authentication shape specified for your Html2Pdf.app account if they differ from this documented example format. The important troubleshooting change here is the waitFor value; test it against the same page and assets.
4. Match the PDF’s CSS media mode to the design
Html2Pdf.app accepts media values screen and print; the documented default is screen. A site’s print stylesheet may hide images, change backgrounds, or use a different font. Conversely, screen rules may be necessary to preserve the on-screen design. Compare the PDF using the mode the page is designed for.
| Setting | Use when | What to inspect |
|---|---|---|
screen |
The PDF should follow the regular screen layout; this is the documented default. | Screen CSS visibility, background and image rules, font declarations. |
print |
The page has print-specific styles intended for document output. | Print rules that hide elements or substitute fonts and images. |
Example JSON request options, to adapt to your account’s documented request format:
{
"url": "https://example.com/report",
"apiKey": "YOUR_API_KEY",
"media": "print",
"waitFor": 3
}
5. Handle images in header and footer templates differently
Header and footer templates have a documented resource restriction: external resources cannot load there. Embed an image as a base64 data URL instead. Templates also do not inherit the source page’s CSS, so include any required styles in the template markup itself.
<div style="font-family: Arial, sans-serif; font-size: 10px;">
<img
src="data:image/png;base64,BASE64_ENCODED_IMAGE_DATA"
alt=""
style="width: 120px; height: auto;"
>
<span>Report header</span>
</div>
Use the correct data URL media type for the image format. This template example shows the embedding approach; place it in the header or footer field supported by your request format. Do not expect a relative URL or remote image URL in a template to load like an image in the page body.
6. Troubleshooting checklist
| Symptom | Likely check | Fix |
|---|---|---|
| All content is blank or styling is missing | Is the source URL public? Can the renderer reach the required CSS, fonts, and images? | Make the page and required resources publicly accessible to the renderer, then regenerate. The official troubleshooting guide recommends these checks. |
| Text appears, but the web font does not | Can the stylesheet and font file be fetched without authentication? Does the page reference the intended font family and weight? | Correct the @font-face source and make both stylesheet and font public. |
| Images or fonts appear inconsistently | Do they load after JavaScript or other asynchronous work? | Try a suitable waitFor value from 0 to 10 seconds. If the resource remains inaccessible, fix access separately. |
| PDF layout differs from the browser | Does the page have separate screen and print CSS? | Set media to the intended mode and check the relevant CSS rules. |
| Only header or footer images are absent | Is the template using a remote image URL or relying on page styles? | Embed the image as a base64 data URL and include needed styles directly in the template. |
| A longer wait has no effect | Is the asset behind authentication, blocked, or at an incorrect URL? | Test the asset URL independently. Waiting addresses timing, not access failures. |
Change one variable at a time and inspect the actual generated PDF after each change. The documented checks do not identify a universal cause for every missing asset, so use the PDF result to narrow down which condition applies to your page.
7. Performance, reliability, and cost considerations
- Wait only as long as needed. Since
waitForadds time before generation, start with a modest delay and increase it only if the page’s resources need more time. The documented maximum is 10 seconds. - Prefer dependable asset URLs. Public, stable URLs avoid dependencies on your browser session or expiring access. This is a practical reliability measure, not a guarantee that every conversion will succeed.
- Check both access and timing. Increasing a delay repeatedly will not repair a bad URL or an authentication requirement.
- Check the page mode before changing page CSS. A media mismatch can make a present asset appear hidden, even when it loaded.
- Use inline data for template images. Header and footer templates cannot load external resources, so waiting or changing the page’s stylesheet does not resolve that restriction.
The cited documentation does not establish a universal conversion time, success rate, or cost for a particular page. Review the service’s current account terms for pricing and limits; diagnose the missing asset with the checks above.
Or skip the browser setup
If your goal is a clean screenshot rather than troubleshooting a PDF conversion, ScreenshotNeo is a website screenshot API and MCP server for developers. One GET request returns a PNG, JPEG, WebP, or PDF. It accepts cookie and consent banners like a visitor and removes 60+ known consent platforms, newsletter popups, and chat widgets before capture; each step can be turned off. Bot checks, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing status. Its MCP server gives AI agents tools to take screenshots, get page information, and capture PDFs.
cURL example, using the documented API call; see the ScreenshotNeo documentation for options:
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
Free includes 1,000 screenshots per month with no card. Paid plans start at $5 for 3,000 screenshots. Sign up for free and get 1,000 screenshots a month with no card.
FAQ
Why are images missing from my Html2Pdf.app PDF?
Start with public reachability of the image URL. If it is in a header or footer template, embed it as a base64 data URL because external resources cannot load there.
Why are web fonts missing from my PDF?
Check that both the stylesheet and font file are publicly reachable without authentication, and that the page declares the font with @font-face as needed.
Will increasing waitFor fix a font that needs a login?
No. It can help when resources load asynchronously, but it cannot grant access to a protected asset.
Should I use screen or print?
Use the mode whose CSS rules match the intended PDF. The documented default is screen; choose print when the page’s print styles are the desired design.


