Puppeteer fullPage screenshot not capturing entire scrollable content in single page app

I’m working with a single page app that has vertical scrolling content. When I try to capture a screenshot of the complete page using Puppeteer, it’s only grabbing what’s currently visible in the viewport instead of the entire scrollable area.

Here’s my current code:

const chrome = await puppeteer.launch(config);
const tab = await chrome.newPage();
await tab.navigate(targetUrl);
await tab.screenshot({ filename: 'capture.png', fullPage: true });
await chrome.close();

Even though I’m using the fullPage option set to true, it’s not working as expected. The screenshot only shows the part that fits in the browser window. Has anyone dealt with this issue before? I need to capture everything including the content that requires scrolling to see.

This behavior usually happens when the SPA hasn’t fully loaded all its content yet. I encountered this exact problem with a React app where fullPage was working but missing dynamic content that loaded after initial render. The solution was adding proper wait conditions before taking the screenshot. Try using await tab.waitForLoadState('networkidle') or wait for specific elements that indicate your content is fully loaded. Also check if your app has lazy loading components that might not be triggering during the screenshot process. Sometimes you need to programmatically scroll to the bottom first to force all content to render, then take the fullPage screenshot. The timing is crucial with SPAs since they load content progressively.

Run into this frequently with SPAs that use virtual scrolling or infinite scroll components. The issue is that fullPage relies on document height detection, but many modern frameworks don’t expand the DOM until content is actually needed. What worked for me was manually calculating the content height first by injecting a script that forces all content to render. You can use await tab.evaluate(() => document.body.scrollHeight) to get the actual content height, then set that as your viewport height before screenshotting. Another approach is to disable any virtual scrolling temporarily through the browser console if your app supports it. Some SPA frameworks also have development flags that can disable lazy rendering which might help during testing scenarios.

had similar issue with vue app - the problem was viewport height was too small so puppeteer couldn’t detect the full content height properly. try setting a larger viewport before screenshot like await tab.setViewport({width: 1920, height: 1080}). also some spas use css transforms or absolute positioning that messes with fullpage detection. worth checking if your content container has proper height values set