I spent two evenings debugging this. Sharing so you don't have to.
The problem
When you call page.screenshot({ fullPage: true }) on a site with a position: fixed header, one of three things usually happens:
The header renders in the middle of the page (not at the top)
The header area is blank at the top of the PDF/PNG
Only the first page shows the header — subsequent "pages" don't
You open the site in a real browser: looks perfect. You open it in Puppeteer's viewport mode: also fine. Only fullPage: true breaks it.
Why this happens
Puppeteer's fullPage: true uses Chrome DevTools Protocol's captureBeyondViewport. Under the hood, Chrome rasterizes the whole document beyond the viewport — but position: fixed elements are painted relative to the current viewport, not the document. So if your script scrolled to the bottom of the page before taking the screenshot, the fixed header is captured at the bottom.
There's also a second issue: many sites have scroll-b
Discussion
Begin the discussion
Begin something meaningful by sharing your ideas.