Puppeteer PDF generation missing images and CSS styling - how to fix?

I’m having trouble with puppeteer when trying to generate PDFs. The main issue is that images and some CSS styles are not showing up in the final PDF output, even though I’m using browser.waitForLoadState() to make sure everything loads properly.

What’s really strange is that when I switch to using browser.screenshot() instead of browser.pdf(), everything renders perfectly with all images and styles intact.

Here’s my current setup:

  • Node.js v8.5.0
  • Puppeteer version 0.10.2
const playwright = require('puppeteer');
const targetUrl = 'https://example-store.com/category/apps';

(async () => {
  const browserInstance = await playwright.launch();
  const newPage = await browserInstance.newPage();
  await newPage.goto(targetUrl);
  await newPage.waitForLoadState({timeout: 120000, waitUntil: 'networkidle', networkIdleTimeout: 3000});
  await newPage.pdf({path: 'output.pdf'});

  // This alternative method works fine:
  // await newPage.screenshot({fullPage: true, path: 'output.png'});

  browserInstance.close();
})()

Any ideas why PDF generation behaves differently than screenshots?

pdf generation uses webkit’s print engine, so css rendering can be diffrent. try addin printBackground: true in your pdf() options and check your image src paths too, they need to be accessible for puppeteer.

I encountered a similar issue recently while generating dynamic invoices. The PDF rendering process in Puppeteer often behaves differently from screenshots due to its reliance on the print rendering engine. Even with the use of waitForLoadState, images that load dynamically or via lazy loading scripts may not be fully rendered before the PDF generation begins. A solution I found effective is to introduce an explicit wait after the page has loaded to ensure that all images are fully loaded. You can use this code snippet: await newPage.waitForFunction(() => Array.from(document.images).every(img => img.complete)) before calling your pdf method. Additionally, make sure to check your CSS for any @media print rules that could potentially hide elements during the rendering process, as the print context behaves differently from screen rendering.

Your Node.js v8.5.0 and Puppeteer 0.10.2 combo is probably the culprit - that’s pretty old and had known PDF rendering bugs. I hit the same issue last year building reports for a client portal. Upgrading fixed most of the missing content problems. If you can’t upgrade, try setting viewport size explicitly before generating the PDF and add a longer manual delay after waitForLoadState. The PDF engine often needs more time than waitForLoadState thinks it does. Also check if your images use relative paths or have CORS issues - those can mess with PDF rendering differently than screenshots.

This topic was automatically closed 24 hours after the last reply. New replies are no longer allowed.