Log in, verify that the protected content is ready, then capture it with await page.screenshot({ path: 'page.png', fullPage: true }). The key is to wait for a page-specific signal: a navigation or network-idle condition alone does not prove that login succeeded or that the content you need has loaded.
Capture a logged-in page in three steps
- Launch Puppeteer and create a page.
- Authenticate using the method the site requires, then navigate to the protected page.
- Wait for a stable marker in the content and take a screenshot with
fullPage: true.
This adaptable example uses an application page that is already accessible after navigation. Replace the URL and selector with values for your site. It is not a tested script for any particular website.
As an Amazon Associate I earn from qualifying purchases.
import puppeteer from 'puppeteer';
const browser = await puppeteer.launch();
try {
const page = await browser.newPage();
await page.goto('https://example.com/account/report', {
waitUntil: 'networkidle2',
});
// Replace with a stable marker for the content you need.
await page.locator('[data-testid="report-content"]').wait();
await page.screenshot({ path: 'page.png', fullPage: true });
} finally {
await browser.close();
}
Puppeteer’s screenshot guide documents navigation and Page.screenshot(); its API reference defines fullPage. The documentation retrieved for this guide is labeled Puppeteer 25.12.0, so check the API documentation for the version installed in your project: Puppeteer screenshot guide and ScreenshotOptions API reference.
Choose the right authentication flow
HTTP authentication
If the protected resource uses HTTP authentication, call page.authenticate() before navigating to it. Supply credentials securely rather than hard-coding them in a script:
#1 Best Overall
await page.authenticate({
username: process.env.USERNAME,
password: process.env.PASSWORD,
});
await page.goto('https://example.com/account/report', {
waitUntil: 'networkidle2',
});
This API is for HTTP authentication, not for filling in an ordinary website sign-in form. Puppeteer enables request interception behind the scenes to implement it, which may affect performance. See Page.authenticate().
Application sign-in form
For a normal website login, visit its sign-in page, use the site’s own form controls, submit the form, and verify an authenticated-state marker before opening the target page. The actual selectors and success signal depend on the site; a dashboard heading, account menu, or protected-content element may be suitable if it reliably appears only after authentication.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
await page.goto('https://example.com/sign-in');
// Replace these selectors with the site's actual form controls.
await page.locator('input[name="email"]').fill(process.env.APP_USERNAME);
await page.locator('input[name="password"]').fill(process.env.APP_PASSWORD);
await page.locator('button[type="submit"]').click();
// Use a marker that appears only in the authenticated state.
await page.locator('[data-testid="account-menu"]').wait();
await page.goto('https://example.com/account/report', {
waitUntil: 'networkidle2',
});
await page.locator('[data-testid="report-content"]').wait();
await page.screenshot({ path: 'page.png', fullPage: true });
The selectors above are examples, not universal login selectors. Puppeteer locators provide waiting and action preconditions; use selectors and a success marker appropriate to the site’s interface. See Puppeteer page interactions and Locator API reference.
Wait for the content, not just the navigation
waitUntil: 'networkidle2' can help let a page settle, but it does not confirm that the correct account is signed in or that the report or other target content is present. Likewise, page.waitForNetworkIdle() waits until the network is idle for at least its configured idle time; that condition is not an application-level readiness check. Pair a navigation or network wait with a selector that represents the content you intend to capture. See Page.waitForNetworkIdle().
Rank #3
A stable content marker is generally more dependable than an arbitrary fixed sleep because it ties the capture to something the page actually renders. Choose a selector that distinguishes the desired logged-in content from a loading state, an error screen, or a sign-in page.
Pages that load content on scroll
A full-page screenshot setting does not guarantee that every lazy-loaded section has been fetched. Before capture, confirm the required sections exist in the page. If the site loads content only as the user scrolls, scroll through the relevant sections and wait for their markers before taking the screenshot. The exact scrolling behavior and readiness checks are site-specific.
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Save the whole page
Set fullPage: true to capture the full document rather than only the current viewport. Providing path saves the image to that file; if you omit the path, the screenshot API can return image data instead. In either case, perform the capture only after your authentication and content checks have succeeded.
Recommended Free Tools
Troubleshooting
- The screenshot shows a sign-in page. Confirm which authentication flow the site uses. Use
page.authenticate()only for HTTP authentication; for an application form, submit the form and wait for a logged-in UI marker before visiting the protected URL. - The screenshot is blank, incomplete, or still loading. Replace a generic timing assumption with a selector for the specific content. Network idle is not proof that the application has rendered the target data.
- Lower sections are missing. Check whether the page loads them only after scrolling. Scroll through the page and wait for those sections to appear before capture.
- HTTP authentication appears to slow requests. Puppeteer implements
page.authenticate()with request interception. Use it only when the resource actually uses HTTP authentication. - The example selector never appears. The sample selector is a placeholder. Inspect the target site’s DOM and choose a stable marker that appears in the intended authenticated state.
Or skip the browser setup
For a page ScreenshotNeo can access, its screenshot API accepts a URL in one GET request and can return a screenshot or PDF. This example saves a WebP screenshot; see the ScreenshotNeo API documentation for authentication and options.
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://example.com/account/report -o shot.webp
ScreenshotNeo removes known cookie and consent banners, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and the response indicates the page verdict and billing status in headers. Its MCP server includes tools for AI agents to take screenshots, get page information, and capture PDFs. The free plan includes 1,000 screenshots per month with no card; paid plans start at $5 for 3,000 screenshots.
Learn about ScreenshotNeo or sign up free for 1,000 screenshots a month, with no card.
Frequently Asked Questions
Which Puppeteer option captures the entire page?
Set fullPage: true in page.screenshot().
Does networkidle2 confirm that a user is logged in?
No. Check a site-specific authenticated-state or content marker; network activity alone does not establish the account state.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

